1
1
import lodashGet from 'lodash/get' ;
2
- import React from 'react' ;
2
+ import React , { useCallback , useEffect } from 'react' ;
3
3
import { Keyboard , View } from 'react-native' ;
4
4
import { withOnyx } from 'react-native-onyx' ;
5
5
import _ from 'underscore' ;
@@ -36,56 +36,34 @@ const defaultProps = {
36
36
...policyDefaultProps ,
37
37
} ;
38
38
39
- class WorkspaceRateAndUnitPage extends React . Component {
40
- constructor ( props ) {
41
- super ( props ) ;
42
- this . submit = this . submit . bind ( this ) ;
43
- this . validate = this . validate . bind ( this ) ;
44
- }
45
-
46
- componentDidMount ( ) {
47
- if ( lodashGet ( this . props , 'policy.customUnits' , [ ] ) . length !== 0 ) {
39
+ function WorkspaceRateAndUnitPage ( props ) {
40
+ const fetchData = useCallback ( ( ) => {
41
+ if ( lodashGet ( props , 'policy.customUnits' , [ ] ) . length !== 0 ) {
48
42
return ;
49
43
}
50
- // When this page is accessed directly from url, the policy.customUnits data won't be available,
51
- // and we should trigger Policy.openWorkspaceReimburseView to get the data
52
44
53
45
BankAccounts . setReimbursementAccountLoading ( true ) ;
54
- Policy . openWorkspaceReimburseView ( this . props . policy . id ) ;
55
- }
56
-
57
- getUnitItems ( ) {
58
- return [
59
- { label : this . props . translate ( 'common.kilometers' ) , value : CONST . CUSTOM_UNITS . DISTANCE_UNIT_KILOMETERS } ,
60
- { label : this . props . translate ( 'common.miles' ) , value : CONST . CUSTOM_UNITS . DISTANCE_UNIT_MILES } ,
61
- ] ;
62
- }
46
+ Policy . openWorkspaceReimburseView ( props . policy . id ) ;
47
+ } , [ props ] ) ;
63
48
64
- getRateDisplayValue ( value ) {
65
- const numValue = this . getNumericValue ( value ) ;
66
- if ( Number . isNaN ( numValue ) ) {
67
- return '' ;
68
- }
69
- return numValue . toString ( ) . replace ( '.' , this . props . toLocaleDigit ( '.' ) ) . substring ( 0 , value . length ) ;
70
- }
49
+ useEffect ( ( ) => {
50
+ fetchData ( ) ;
51
+ } , [ fetchData ] ) ;
71
52
72
- getNumericValue ( value ) {
73
- const numValue = NumberUtils . parseFloatAnyLocale ( value . toString ( ) ) ;
74
- if ( Number . isNaN ( numValue ) ) {
75
- return NaN ;
76
- }
77
- return numValue . toFixed ( 3 ) ;
78
- }
53
+ const getUnitItems = ( ) => [
54
+ { label : props . translate ( 'common.kilometers' ) , value : CONST . CUSTOM_UNITS . DISTANCE_UNIT_KILOMETERS } ,
55
+ { label : props . translate ( 'common.miles' ) , value : CONST . CUSTOM_UNITS . DISTANCE_UNIT_MILES } ,
56
+ ] ;
79
57
80
- saveUnitAndRate ( unit , rate ) {
81
- const distanceCustomUnit = _ . find ( lodashGet ( this . props , 'policy.customUnits' , { } ) , ( u ) => u . name === CONST . CUSTOM_UNITS . NAME_DISTANCE ) ;
58
+ const saveUnitAndRate = ( unit , rate ) => {
59
+ const distanceCustomUnit = _ . find ( lodashGet ( props , 'policy.customUnits' , { } ) , ( u ) => u . name === CONST . CUSTOM_UNITS . NAME_DISTANCE ) ;
82
60
if ( ! distanceCustomUnit ) {
83
61
return ;
84
62
}
85
63
const currentCustomUnitRate = _ . find ( lodashGet ( distanceCustomUnit , 'rates' , { } ) , ( r ) => r . name === CONST . CUSTOM_UNITS . DEFAULT_RATE ) ;
86
64
const unitID = lodashGet ( distanceCustomUnit , 'customUnitID' , '' ) ;
87
65
const unitName = lodashGet ( distanceCustomUnit , 'name' , '' ) ;
88
- const rateNumValue = PolicyUtils . getNumericValue ( rate , this . props . toLocaleDigit ) ;
66
+ const rateNumValue = PolicyUtils . getNumericValue ( rate , props . toLocaleDigit ) ;
89
67
90
68
const newCustomUnit = {
91
69
customUnitID : unitID ,
@@ -96,19 +74,19 @@ class WorkspaceRateAndUnitPage extends React.Component {
96
74
rate : rateNumValue * CONST . POLICY . CUSTOM_UNIT_RATE_BASE_OFFSET ,
97
75
} ,
98
76
} ;
99
- Policy . updateWorkspaceCustomUnitAndRate ( this . props . policy . id , distanceCustomUnit , newCustomUnit , this . props . policy . lastModified ) ;
100
- }
77
+ Policy . updateWorkspaceCustomUnitAndRate ( props . policy . id , distanceCustomUnit , newCustomUnit , props . policy . lastModified ) ;
78
+ } ;
101
79
102
- submit ( values ) {
103
- this . saveUnitAndRate ( values . unit , values . rate ) ;
80
+ const submit = ( values ) => {
81
+ saveUnitAndRate ( values . unit , values . rate ) ;
104
82
Keyboard . dismiss ( ) ;
105
- Navigation . goBack ( ROUTES . WORKSPACE_REIMBURSE . getRoute ( this . props . policy . id ) ) ;
106
- }
83
+ Navigation . goBack ( ROUTES . WORKSPACE_REIMBURSE . getRoute ( props . policy . id ) ) ;
84
+ } ;
107
85
108
- validate ( values ) {
86
+ const validate = ( values ) => {
109
87
const errors = { } ;
110
- const decimalSeparator = this . props . toLocaleDigit ( '.' ) ;
111
- const outputCurrency = lodashGet ( this . props , 'policy.outputCurrency' , CONST . CURRENCY . USD ) ;
88
+ const decimalSeparator = props . toLocaleDigit ( '.' ) ;
89
+ const outputCurrency = lodashGet ( props , 'policy.outputCurrency' , CONST . CURRENCY . USD ) ;
112
90
// Allow one more decimal place for accuracy
113
91
const rateValueRegex = RegExp ( String . raw `^-?\d{0,8}([${ getPermittedDecimalSeparator ( decimalSeparator ) } ]\d{1,${ CurrencyUtils . getCurrencyDecimals ( outputCurrency ) + 1 } })?$` , 'i' ) ;
114
92
if ( ! rateValueRegex . test ( values . rate ) || values . rate === '' ) {
@@ -117,73 +95,73 @@ class WorkspaceRateAndUnitPage extends React.Component {
117
95
errors . rate = 'workspace.reimburse.lowRateError' ;
118
96
}
119
97
return errors ;
120
- }
121
-
122
- render ( ) {
123
- const distanceCustomUnit = _ . find ( lodashGet ( this . props , 'policy.customUnits' , { } ) , ( unit ) => unit . name === CONST . CUSTOM_UNITS . NAME_DISTANCE ) ;
124
- const distanceCustomRate = _ . find ( lodashGet ( distanceCustomUnit , 'rates' , { } ) , ( rate ) => rate . name === CONST . CUSTOM_UNITS . DEFAULT_RATE ) ;
125
- return (
126
- < WorkspacePageWithSections
127
- headerText = { this . props . translate ( 'workspace.reimburse.trackDistance' ) }
128
- route = { this . props . route }
129
- guidesCallTaskID = { CONST . GUIDES_CALL_TASK_IDS . WORKSPACE_REIMBURSE }
130
- shouldSkipVBBACall
131
- backButtonRoute = { ROUTES . WORKSPACE_REIMBURSE . getRoute ( this . props . policy . id ) }
132
- >
133
- { ( ) => (
134
- < FormProvider
135
- formID = { ONYXKEYS . FORMS . WORKSPACE_RATE_AND_UNIT_FORM }
136
- submitButtonText = { this . props . translate ( 'common.save' ) }
137
- style = { [ this . props . themeStyles . mh5 , this . props . themeStyles . flexGrow1 ] }
138
- scrollContextEnabled
139
- validate = { this . validate }
140
- onSubmit = { this . submit }
141
- enabledWhenOffline
98
+ } ;
99
+
100
+ const distanceCustomUnit = _ . find ( lodashGet ( props , 'policy.customUnits' , { } ) , ( unit ) => unit . name === CONST . CUSTOM_UNITS . NAME_DISTANCE ) ;
101
+ const distanceCustomRate = _ . find ( lodashGet ( distanceCustomUnit , 'rates' , { } ) , ( rate ) => rate . name === CONST . CUSTOM_UNITS . DEFAULT_RATE ) ;
102
+
103
+ return (
104
+ < WorkspacePageWithSections
105
+ headerText = { props . translate ( 'workspace.reimburse.trackDistance' ) }
106
+ route = { props . route }
107
+ guidesCallTaskID = { CONST . GUIDES_CALL_TASK_IDS . WORKSPACE_REIMBURSE }
108
+ shouldSkipVBBACall
109
+ backButtonRoute = { ROUTES . WORKSPACE_REIMBURSE . getRoute ( props . policy . id ) }
110
+ >
111
+ { ( ) => (
112
+ < FormProvider
113
+ formID = { ONYXKEYS . FORMS . WORKSPACE_RATE_AND_UNIT_FORM }
114
+ submitButtonText = { props . translate ( 'common.save' ) }
115
+ style = { [ props . themeStyles . mh5 , props . themeStyles . flexGrow1 ] }
116
+ scrollContextEnabled
117
+ validate = { validate }
118
+ onSubmit = { submit }
119
+ enabledWhenOffline
120
+ >
121
+ < OfflineWithFeedback
122
+ errors = { {
123
+ ...lodashGet ( distanceCustomUnit , 'errors' , { } ) ,
124
+ ...lodashGet ( distanceCustomRate , 'errors' , { } ) ,
125
+ } }
126
+ pendingAction = { lodashGet ( distanceCustomUnit , 'pendingAction' ) || lodashGet ( distanceCustomRate , 'pendingAction' ) }
127
+ onClose = { ( ) =>
128
+ Policy . clearCustomUnitErrors ( props . policy . id , lodashGet ( distanceCustomUnit , 'customUnitID' , '' ) , lodashGet ( distanceCustomRate , 'customUnitRateID' , '' ) )
129
+ }
142
130
>
143
- < OfflineWithFeedback
144
- errors = { {
145
- ...lodashGet ( distanceCustomUnit , 'errors' , { } ) ,
146
- ...lodashGet ( distanceCustomRate , 'errors' , { } ) ,
147
- } }
148
- pendingAction = { lodashGet ( distanceCustomUnit , 'pendingAction' ) || lodashGet ( distanceCustomRate , 'pendingAction' ) }
149
- onClose = { ( ) =>
150
- Policy . clearCustomUnitErrors ( this . props . policy . id , lodashGet ( distanceCustomUnit , 'customUnitID' , '' ) , lodashGet ( distanceCustomRate , 'customUnitRateID' , '' ) )
151
- }
152
- >
131
+ < InputWrapper
132
+ InputComponent = { TextInput }
133
+ role = { CONST . ACCESSIBILITY_ROLE . TEXT }
134
+ inputID = "rate"
135
+ containerStyles = { [ props . themeStyles . mt4 ] }
136
+ defaultValue = { PolicyUtils . getUnitRateValue ( distanceCustomRate , props . toLocaleDigit ) }
137
+ label = { props . translate ( 'workspace.reimburse.trackDistanceRate' ) }
138
+ aria-label = { props . translate ( 'workspace.reimburse.trackDistanceRate' ) }
139
+ placeholder = { lodashGet ( props , 'policy.outputCurrency' , CONST . CURRENCY . USD ) }
140
+ autoCompleteType = "off"
141
+ autoCorrect = { false }
142
+ inputMode = { CONST . INPUT_MODE . DECIMAL }
143
+ maxLength = { 12 }
144
+ />
145
+
146
+ < View style = { [ props . themeStyles . mt4 ] } >
153
147
< InputWrapper
154
- InputComponent = { TextInput }
155
- role = { CONST . ACCESSIBILITY_ROLE . TEXT }
156
- inputID = "rate"
157
- containerStyles = { [ this . props . themeStyles . mt4 ] }
158
- defaultValue = { PolicyUtils . getUnitRateValue ( distanceCustomRate , this . props . toLocaleDigit ) }
159
- label = { this . props . translate ( 'workspace.reimburse.trackDistanceRate' ) }
160
- aria-label = { this . props . translate ( 'workspace.reimburse.trackDistanceRate' ) }
161
- placeholder = { lodashGet ( this . props , 'policy.outputCurrency' , CONST . CURRENCY . USD ) }
162
- autoCompleteType = "off"
163
- autoCorrect = { false }
164
- inputMode = { CONST . INPUT_MODE . DECIMAL }
165
- maxLength = { 12 }
148
+ InputComponent = { Picker }
149
+ inputID = "unit"
150
+ label = { props . translate ( 'workspace.reimburse.trackDistanceUnit' ) }
151
+ items = { getUnitItems ( ) }
152
+ defaultValue = { lodashGet ( distanceCustomUnit , 'attributes.unit' , CONST . CUSTOM_UNITS . DISTANCE_UNIT_MILES ) }
166
153
/>
167
-
168
- < View style = { [ this . props . themeStyles . mt4 ] } >
169
- < InputWrapper
170
- InputComponent = { Picker }
171
- inputID = "unit"
172
- label = { this . props . translate ( 'workspace.reimburse.trackDistanceUnit' ) }
173
- items = { this . getUnitItems ( ) }
174
- defaultValue = { lodashGet ( distanceCustomUnit , 'attributes.unit' , CONST . CUSTOM_UNITS . DISTANCE_UNIT_MILES ) }
175
- />
176
- </ View >
177
- </ OfflineWithFeedback >
178
- </ FormProvider >
179
- ) }
180
- </ WorkspacePageWithSections >
181
- ) ;
182
- }
154
+ </ View >
155
+ </ OfflineWithFeedback >
156
+ </ FormProvider >
157
+ ) }
158
+ </ WorkspacePageWithSections >
159
+ ) ;
183
160
}
184
161
185
162
WorkspaceRateAndUnitPage . propTypes = propTypes ;
186
163
WorkspaceRateAndUnitPage . defaultProps = defaultProps ;
164
+ WorkspaceRateAndUnitPage . displayName = 'WorkspaceRateAndUnitPage' ;
187
165
188
166
export default compose (
189
167
withPolicy ,
0 commit comments