diff --git a/packages/bot-web-ui/src/components/quick-strategy/quick-strategy.jsx b/packages/bot-web-ui/src/components/quick-strategy/quick-strategy.jsx index c4ab8a2bd349..32b59e041c94 100644 --- a/packages/bot-web-ui/src/components/quick-strategy/quick-strategy.jsx +++ b/packages/bot-web-ui/src/components/quick-strategy/quick-strategy.jsx @@ -35,6 +35,10 @@ const InputSize = ({ touched, is_mobile, getFieldNames, + toggleValuesFlags, + setValidationErrors, + validateQuickStrategy, + values, }) => { const input_name = Object.freeze({ 0: 'input_size', @@ -58,7 +62,11 @@ const InputSize = ({ onChangeInputValue(input_name[active_index], e); }} onFocus={e => setCurrentFocus(e.currentTarget.name)} - onBlur={() => setCurrentFocus(null)} + onBlur={e => { + setCurrentFocus(null); + toggleValuesFlags(e.currentTarget.name); + setValidationErrors(validateQuickStrategy(values)); + }} placeholder='2' trailing_icon={ ( - - {({ errors, handleChange, values, isSubmitting, setFieldValue, touched, submitForm }) => { - // Check values in favour of isValid, this is a hack to persist validation through tab switching. - const validation_errors = validateQuickStrategy(values); - const is_valid = Object.keys(validation_errors).length === 0; - - const is_submit_enabled = !isSubmitting && is_valid; + toggleValuesFlags, +}) => { + const [validation_errors, setValidationErrors] = React.useState({}); + let formValues = {}; + React.useEffect(() => { + // Check values in favour of isValid, this is a hack to persist validation through tab switching. + setValidationErrors(validateQuickStrategy(formValues)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return ( + + {({ errors, handleChange, values, isSubmitting, setFieldValue, touched, submitForm }) => { + formValues = values; + const is_valid = Object.keys(validation_errors).length === 0; + const is_submit_enabled = !isSubmitting && is_valid; - return ( -
- -
-
{description}
-
- - {({ field }) => ( - <> - {is_mobile ? ( - { - onChangeDropdownItem('symbol', e.target.value, setFieldValue); - }} - /> - ) : ( - { - onHideDropdownList('symbol', values[field.name], setFieldValue); - }} - onItemSelection={({ value }) => { - onChangeDropdownItem('symbol', value, setFieldValue); - }} - onScrollStop={() => onScrollStopDropdownList('symbol')} - leading_icon={ - selected_symbol.value && ( - - ) - } - /> - )} - - )} - -
-
- - {({ field }) => ( - <> - {is_mobile ? ( - { - onChangeDropdownItem( - 'trade-type', - e.target.value, - setFieldValue - ); - }} - /> - ) : ( - { - onHideDropdownList( - 'trade-type', - values[field.name], - setFieldValue - ); - }} - onItemSelection={({ value }) => { - onChangeDropdownItem('trade-type', value, setFieldValue); - }} - onScrollStop={() => onScrollStopDropdownList('trade-type')} - leading_icon={ - selected_trade_type.icon && ( - - - - - ) - } - /> - )} - - )} - -
-
- - {({ field }) => ( - <> - {is_mobile ? ( - { - onChangeDropdownItem( - 'duration-unit', - e.target.value, - setFieldValue - ); - }} - /> - ) : ( - { - onHideDropdownList( - 'duration-unit', - values[field.name], - setFieldValue - ); - }} - onItemSelection={({ value }) => { - onChangeDropdownItem('duration-unit', value, setFieldValue); - }} - onScrollStop={() => onScrollStopDropdownList('duration-unit')} - /> - )} - - )} - - - {({ field }) => ( - { - handleChange(e); - onChangeInputValue('input_duration_value', e); - }} - onFocus={e => setCurrentFocus(e.currentTarget.name)} - onBlur={() => setCurrentFocus(null)} - placeholder='5' - trailing_icon={ - - - - } - /> - )} - -
-
- - {({ field }) => ( - { - handleChange(e); - onChangeInputValue('input_stake', e); - }} - onFocus={e => setCurrentFocus(e.currentTarget.name)} - onBlur={() => setCurrentFocus(null)} - placeholder='10' - trailing_icon={ - - - - } - /> - )} - - - {({ field }) => ( - { - handleChange(e); - onChangeInputValue('input_loss', e); - }} - onFocus={e => setCurrentFocus(e.currentTarget.name)} - onBlur={() => setCurrentFocus(null)} - placeholder='5000' - trailing_icon={ - - - - } - /> - )} - -
+ return ( + +
- +
{description}
+
+ + {({ field }) => ( + <> + {is_mobile ? ( + { + onChangeDropdownItem( + 'symbol', + e.target.value, + setFieldValue + ); + }} + /> + ) : ( + { + onHideDropdownList( + 'symbol', + values[field.name], + setFieldValue + ); + }} + onItemSelection={({ value }) => { + onChangeDropdownItem('symbol', value, setFieldValue); + }} + onScrollStop={() => onScrollStopDropdownList('symbol')} + leading_icon={ + selected_symbol.value && ( + + ) + } + /> + )} + + )} + +
+
+ + {({ field }) => ( + <> + {is_mobile ? ( + { + onChangeDropdownItem( + 'trade-type', + e.target.value, + setFieldValue + ); + }} + /> + ) : ( + { + onHideDropdownList( + 'trade-type', + values[field.name], + setFieldValue + ); + }} + onItemSelection={({ value }) => { + onChangeDropdownItem('trade-type', value, setFieldValue); + }} + onScrollStop={() => onScrollStopDropdownList('trade-type')} + leading_icon={ + selected_trade_type.icon && ( + + + + + ) + } + /> + )} + + )} + +
+
+ + {({ field }) => ( + <> + {is_mobile ? ( + { + onChangeDropdownItem( + 'duration-unit', + e.target.value, + setFieldValue + ); + }} + /> + ) : ( + { + onHideDropdownList( + 'duration-unit', + values[field.name], + setFieldValue + ); + }} + onItemSelection={({ value }) => { + onChangeDropdownItem('duration-unit', value, setFieldValue); + }} + onScrollStop={() => onScrollStopDropdownList('duration-unit')} + /> + )} + + )} + + + {({ field }) => ( + { + handleChange(e); + onChangeInputValue('input_duration_value', e); + }} + onFocus={e => setCurrentFocus(e.currentTarget.name)} + onBlur={e => { + setCurrentFocus(null); + toggleValuesFlags(e.currentTarget.name); + setValidationErrors(validateQuickStrategy(values)); + }} + placeholder='5' + trailing_icon={ + + + + } + /> + )} + +
+
+ + {({ field }) => ( + { + handleChange(e); + onChangeInputValue('input_stake', e); + }} + onFocus={e => setCurrentFocus(e.currentTarget.name)} + onBlur={e => { + setCurrentFocus(null); + toggleValuesFlags(e.currentTarget.name); + setValidationErrors(validateQuickStrategy(values)); + }} + placeholder='10' + trailing_icon={ + + + + } + /> + )} + + + {({ field }) => ( + { + handleChange(e); + onChangeInputValue('input_loss', e); + }} + onFocus={e => { + setCurrentFocus(e.currentTarget.name); + toggleValuesFlags(e.currentTarget.name); + setValidationErrors(validateQuickStrategy(values)); + }} + onBlur={() => setCurrentFocus(null)} + placeholder='5000' + trailing_icon={ + + + + } + /> + )} + +
+
+ - - {({ field }) => ( - { - handleChange(e); - onChangeInputValue('input_profit', e); - }} - onFocus={e => setCurrentFocus(e.currentTarget.name)} - onBlur={() => setCurrentFocus(null)} - placeholder='5000' - trailing_icon={ - - - - } - /> - )} - + + {({ field }) => ( + { + handleChange(e); + onChangeInputValue('input_profit', e); + }} + onFocus={e => { + setCurrentFocus(e.currentTarget.name); + toggleValuesFlags(e.currentTarget.name); + setValidationErrors(validateQuickStrategy(values)); + }} + onBlur={() => setCurrentFocus(null)} + placeholder='5000' + trailing_icon={ + + + + } + /> + )} + +
-
-
-
- - {!is_mobile && ( + +
+ + {!is_mobile && ( +
- - ); - }} - -); +
+
+ + ); + }} +
+ ); +}; const MarketOption = ({ symbol }) => (
@@ -511,6 +569,7 @@ const ContentRenderer = props => { selected_trade_type, setCurrentFocus, selected_duration_unit, + toggleValuesFlags, } = props; const symbol_dropdown_options = symbol_dropdown .map(symbol => ({ @@ -553,6 +612,7 @@ const ContentRenderer = props => { selected_duration_unit={selected_duration_unit} description={description} setCurrentFocus={setCurrentFocus} + toggleValuesFlags={toggleValuesFlags} />
); @@ -624,6 +684,7 @@ QuickStrategy.propTypes = { export default connect(({ run_panel, quick_strategy, ui }) => ({ active_index: quick_strategy.active_index, + toggleValuesFlags: quick_strategy.toggleValuesFlags, createStrategy: quick_strategy.createStrategy, duration_unit_dropdown: quick_strategy.duration_unit_dropdown, getSizeDesc: quick_strategy.getSizeDesc, diff --git a/packages/bot-web-ui/src/stores/quick-strategy-store.js b/packages/bot-web-ui/src/stores/quick-strategy-store.js index eefe6c748fc5..ce9951410d21 100644 --- a/packages/bot-web-ui/src/stores/quick-strategy-store.js +++ b/packages/bot-web-ui/src/stores/quick-strategy-store.js @@ -26,6 +26,7 @@ export default class QuickStrategyStore { @observable symbol_dropdown = []; @observable trade_type_dropdown = []; @observable duration_unit_dropdown = []; + @observable values_flags = []; @computed get initial_values() { @@ -176,6 +177,13 @@ export default class QuickStrategyStore { } } + @action.bound + toggleValuesFlags(value_flag) { + if (!this.values_flags.includes(value_flag)) { + this.values_flags.push(value_flag); + } + } + @action.bound async createStrategy({ button }) { const symbol = this.selected_symbol.value; @@ -450,7 +458,7 @@ export default class QuickStrategyStore { return; } - if (number_fields.includes(key)) { + if (this.values_flags.includes(key) && number_fields.includes(key)) { if (isNaN(value)) { errors[key] = localize('Must be a number'); } else if (value <= 0) { @@ -460,12 +468,11 @@ export default class QuickStrategyStore { } } - if (value === '') { + if (this.values_flags.includes(key) && value === '') { errors[key] = localize('Field cannot be empty'); } }); - - if (this.active_index === 0 && values['quick-strategy__size'] < 2) { + if (this.active_index === 0 && values['quick-strategy__size'] > 0 && values['quick-strategy__size'] < 2) { errors['quick-strategy__size'] = localize('Value must be higher than 2'); }