Skip to content

Commit

Permalink
Merge pull request #7931 from kakajann/allow-only-numbers-track-dista…
Browse files Browse the repository at this point in the history
…nce-rate

Disable letters in Rate under Track Distance
  • Loading branch information
pecanoro authored Mar 14, 2022
2 parents 0415470 + 4ea4ad1 commit 39e1ad2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 38 deletions.
2 changes: 2 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ const CONST = {
KEYBOARD_TYPE: {
PHONE_PAD: 'phone-pad',
NUMBER_PAD: 'number-pad',
DECIMAL_PAD: 'decimal-pad',
},

ATTACHMENT_PICKER_TYPE: {
Expand Down Expand Up @@ -589,6 +590,7 @@ const CONST = {
CARD_SECURITY_CODE: /^[0-9]{3,4}$/,
CARD_EXPIRATION_DATE: /^(0[1-9]|1[0-2])([^0-9])?([0-9]{4}|([0-9]{2}))$/,
PAYPAL_ME_USERNAME: /^[a-zA-Z0-9]+$/,
RATE_VALUE: /^\d+(\.\d*)?$/,

// Adapted from: https://gist.github.com/dperini/729294
// eslint-disable-next-line max-len
Expand Down
91 changes: 53 additions & 38 deletions src/pages/workspace/reimburse/WorkspaceReimburseNoVBAView.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import compose from '../../../libs/compose';
import ONYXKEYS from '../../../ONYXKEYS';
import * as Policy from '../../../libs/actions/Policy';
import withFullPolicy from '../withFullPolicy';
import CONST from '../../../CONST';

const propTypes = {
/** The policy ID currently being configured */
Expand All @@ -44,29 +45,6 @@ const propTypes = {
};

class WorkspaceReimburseNoVBAView extends React.Component {
unitItems = [
{
label: this.props.translate('workspace.reimburse.kilometers'),
value: 'km',
},
{
label: this.props.translate('workspace.reimburse.miles'),
value: 'mi',
},
];

/**
* Set the rate throttled by 3 seconds so the user does not have to type over the corrected value
*/
updateRateValueThrottled = _.throttle((value) => {
this.setState({rateValue: this.getRateDisplayValue(value)});
Policy.setCustomUnitRate(this.props.policyID, this.state.unitID, {
customUnitRateID: this.state.rateID,
name: this.state.rateName,
rate: value * 100,
}, null);
}, 3000, {leading: false, trailing: true});

constructor(props) {
super(props);
this.state = {
Expand All @@ -78,31 +56,40 @@ class WorkspaceReimburseNoVBAView extends React.Component {
rateValue: this.getRateDisplayValue(lodashGet(props, 'policy.customUnit.rate.value', 0) / 100),
outputCurrency: lodashGet(props, 'policy.outputCurrency', ''),
};

this.unitItems = [
{
label: this.props.translate('workspace.reimburse.kilometers'),
value: 'km',
},
{
label: this.props.translate('workspace.reimburse.miles'),
value: 'mi',
},
];

this.debounceUpdateOnCursorMove = this.debounceUpdateOnCursorMove.bind(this);
this.updateRateValueDebounced = _.debounce(this.updateRateValue.bind(this), 1000);
}

getRateDisplayValue(value) {
const numValue = parseFloat(value);
if (Number.isNaN(numValue)) {
return '';
}
const fraction = numValue.toString().split('.')[1];
return !fraction || fraction.length < 2
? numValue.toFixed(2)
: numValue.toString();

return numValue.toFixed(2);
}

setRate(value) {
const numValue = parseFloat(value);
if (Number.isNaN(numValue)) {
this.setState({rateValue: ''});
return;
}

// Set the immediate value so the user does not lose the input
this.setState({rateValue: numValue.toString()});

// Set the corrected value with a delay and sync to the server
this.updateRateValueThrottled(numValue);
const isInvalidRateValue = value !== '' && !CONST.REGEX.RATE_VALUE.test(value);

this.setState(prevState => ({
rateValue: !isInvalidRateValue ? value : prevState.rateValue,
}), () => {
// Set the corrected value with a delay and sync to the server
this.updateRateValueDebounced(this.state.rateValue);
});
}

setUnit(value) {
Expand All @@ -115,6 +102,32 @@ class WorkspaceReimburseNoVBAView extends React.Component {
}, null);
}

debounceUpdateOnCursorMove(event) {
if (!_.contains(['ArrowLeft', 'ArrowRight'], event.key)) {
return;
}

this.updateRateValueDebounced(this.state.rateValue);
}

updateRateValue(value) {
const numValue = parseFloat(value);

if (_.isNaN(numValue)) {
return;
}

this.setState({
rateValue: numValue.toFixed(2),
});

Policy.setCustomUnitRate(this.props.policyID, this.state.unitID, {
customUnitRateID: this.state.rateID,
name: this.state.rateName,
rate: numValue.toFixed(2) * 100,
}, null);
}

render() {
return (
<>
Expand Down Expand Up @@ -159,6 +172,8 @@ class WorkspaceReimburseNoVBAView extends React.Component {
value={this.state.rateValue}
autoCompleteType="off"
autoCorrect={false}
keyboardType={CONST.KEYBOARD_TYPE.DECIMAL_PAD}
onKeyPress={this.debounceUpdateOnCursorMove}
/>
</View>
<View style={[styles.unitCol]}>
Expand Down

0 comments on commit 39e1ad2

Please sign in to comment.