Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
dfd590e5
Commit
dfd590e5
authored
Mar 11, 2024
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix contract method form fields value foramatting
parent
e8c97e61
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
68 additions
and
36 deletions
+68
-36
ContractMethodFieldInput.tsx
ui/address/contract/methodForm/ContractMethodFieldInput.tsx
+13
-4
ContractMethodFormOutputs.tsx
ui/address/contract/methodForm/ContractMethodFormOutputs.tsx
+2
-2
useFormatFieldValue.tsx
ui/address/contract/methodForm/useFormatFieldValue.tsx
+43
-0
useValidateField.tsx
ui/address/contract/methodForm/useValidateField.tsx
+10
-11
utils.ts
ui/address/contract/methodForm/utils.ts
+0
-19
No files found.
ui/address/contract/methodForm/ContractMethodFieldInput.tsx
View file @
dfd590e5
...
@@ -10,6 +10,7 @@ import ClearButton from 'ui/shared/ClearButton';
...
@@ -10,6 +10,7 @@ import ClearButton from 'ui/shared/ClearButton';
import
ContractMethodFieldLabel
from
'
./ContractMethodFieldLabel
'
;
import
ContractMethodFieldLabel
from
'
./ContractMethodFieldLabel
'
;
import
ContractMethodMultiplyButton
from
'
./ContractMethodMultiplyButton
'
;
import
ContractMethodMultiplyButton
from
'
./ContractMethodMultiplyButton
'
;
import
useArgTypeMatchInt
from
'
./useArgTypeMatchInt
'
;
import
useArgTypeMatchInt
from
'
./useArgTypeMatchInt
'
;
import
useFormatFieldValue
from
'
./useFormatFieldValue
'
;
import
useValidateField
from
'
./useValidateField
'
;
import
useValidateField
from
'
./useValidateField
'
;
interface
Props
{
interface
Props
{
...
@@ -29,15 +30,22 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
...
@@ -29,15 +30,22 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
const
argTypeMatchInt
=
useArgTypeMatchInt
({
argType
:
data
.
type
});
const
argTypeMatchInt
=
useArgTypeMatchInt
({
argType
:
data
.
type
});
const
validate
=
useValidateField
({
isOptional
,
argType
:
data
.
type
,
argTypeMatchInt
});
const
validate
=
useValidateField
({
isOptional
,
argType
:
data
.
type
,
argTypeMatchInt
});
const
format
=
useFormatFieldValue
({
argType
:
data
.
type
,
argTypeMatchInt
});
const
{
control
,
setValue
,
getValues
}
=
useFormContext
();
const
{
control
,
setValue
,
getValues
}
=
useFormContext
();
const
{
field
,
fieldState
}
=
useController
({
control
,
name
,
rules
:
{
validate
,
required
:
isOptional
?
false
:
'
Field is required
'
}
});
const
{
field
,
fieldState
}
=
useController
({
control
,
name
,
rules
:
{
validate
}
});
const
inputBgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
inputBgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
nativeCoinRowBgColor
=
useColorModeValue
(
'
gray.100
'
,
'
gray.700
'
);
const
nativeCoinRowBgColor
=
useColorModeValue
(
'
gray.100
'
,
'
gray.700
'
);
const
hasMultiplyButton
=
argTypeMatchInt
&&
Number
(
argTypeMatchInt
.
power
)
>=
64
;
const
hasMultiplyButton
=
argTypeMatchInt
&&
Number
(
argTypeMatchInt
.
power
)
>=
64
;
const
handleChange
=
React
.
useCallback
((
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
formattedValue
=
format
(
event
.
target
.
value
);
field
.
onChange
(
formattedValue
);
// data send back to hook form
setValue
(
name
,
formattedValue
);
// UI state
},
[
field
,
name
,
setValue
,
format
]);
const
handleClear
=
React
.
useCallback
(()
=>
{
const
handleClear
=
React
.
useCallback
(()
=>
{
setValue
(
name
,
''
);
setValue
(
name
,
''
);
ref
.
current
?.
focus
();
ref
.
current
?.
focus
();
...
@@ -46,9 +54,9 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
...
@@ -46,9 +54,9 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
const
handleMultiplyButtonClick
=
React
.
useCallback
((
power
:
number
)
=>
{
const
handleMultiplyButtonClick
=
React
.
useCallback
((
power
:
number
)
=>
{
const
zeroes
=
Array
(
power
).
fill
(
'
0
'
).
join
(
''
);
const
zeroes
=
Array
(
power
).
fill
(
'
0
'
).
join
(
''
);
const
value
=
getValues
(
name
);
const
value
=
getValues
(
name
);
const
newValue
=
value
?
value
+
zeroes
:
'
1
'
+
zeroes
;
const
newValue
=
format
(
value
?
value
+
zeroes
:
'
1
'
+
zeroes
)
;
setValue
(
name
,
newValue
);
setValue
(
name
,
newValue
);
},
[
getValues
,
name
,
setValue
]);
},
[
format
,
getValues
,
name
,
setValue
]);
const
error
=
fieldState
.
error
;
const
error
=
fieldState
.
error
;
...
@@ -76,6 +84,7 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
...
@@ -76,6 +84,7 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
allowNegative
:
!
argTypeMatchInt
.
isUnsigned
,
allowNegative
:
!
argTypeMatchInt
.
isUnsigned
,
}
:
{})
}
}
:
{})
}
ref=
{
ref
}
ref=
{
ref
}
onChange=
{
handleChange
}
required=
{
!
isOptional
}
required=
{
!
isOptional
}
isInvalid=
{
Boolean
(
error
)
}
isInvalid=
{
Boolean
(
error
)
}
placeholder=
{
data
.
type
}
placeholder=
{
data
.
type
}
...
@@ -84,7 +93,7 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
...
@@ -84,7 +93,7 @@ const ContractMethodFieldInput = ({ data, hideLabel, path: name, className, isDi
paddingRight=
{
hasMultiplyButton
?
'
120px
'
:
'
40px
'
}
paddingRight=
{
hasMultiplyButton
?
'
120px
'
:
'
40px
'
}
/>
/>
<
InputRightElement
w=
"auto"
right=
{
1
}
>
<
InputRightElement
w=
"auto"
right=
{
1
}
>
{
typeof
field
.
value
===
'
string
'
&&
field
.
value
.
replace
(
'
\n
'
,
''
)
&&
<
ClearButton
onClick=
{
handleClear
}
isDisabled=
{
isDisabled
}
/>
}
{
field
.
value
!==
undefined
&&
field
.
value
!==
''
&&
<
ClearButton
onClick=
{
handleClear
}
isDisabled=
{
isDisabled
}
/>
}
{
hasMultiplyButton
&&
<
ContractMethodMultiplyButton
onClick=
{
handleMultiplyButtonClick
}
isDisabled=
{
isDisabled
}
/>
}
{
hasMultiplyButton
&&
<
ContractMethodMultiplyButton
onClick=
{
handleMultiplyButtonClick
}
isDisabled=
{
isDisabled
}
/>
}
</
InputRightElement
>
</
InputRightElement
>
</
InputGroup
>
</
InputGroup
>
...
...
ui/address/contract/methodForm/ContractMethodFormOutputs.tsx
View file @
dfd590e5
...
@@ -20,11 +20,11 @@ const ContractMethodFormOutputs = ({ data }: Props) => {
...
@@ -20,11 +20,11 @@ const ContractMethodFormOutputs = ({ data }: Props) => {
<
p
>
<
p
>
{
data
.
map
(({
type
,
name
},
index
)
=>
{
{
data
.
map
(({
type
,
name
},
index
)
=>
{
return
(
return
(
<>
<
React
.
Fragment
key=
{
index
}
>
<
chakra
.
span
fontWeight=
{
500
}
>
{
name
}
</
chakra
.
span
>
<
chakra
.
span
fontWeight=
{
500
}
>
{
name
}
</
chakra
.
span
>
<
span
>
{
name
?
`(${ type })`
:
type
}
</
span
>
<
span
>
{
name
?
`(${ type })`
:
type
}
</
span
>
{
index
<
data
.
length
-
1
&&
<
span
>
,
</
span
>
}
{
index
<
data
.
length
-
1
&&
<
span
>
,
</
span
>
}
</>
</
React
.
Fragment
>
);
);
})
}
})
}
</
p
>
</
p
>
...
...
ui/address/contract/methodForm/useFormatFieldValue.tsx
0 → 100644
View file @
dfd590e5
import
React
from
'
react
'
;
import
type
{
SmartContractMethodArgType
}
from
'
types/api/contract
'
;
import
type
{
MatchInt
}
from
'
./useArgTypeMatchInt
'
;
interface
Params
{
argType
:
SmartContractMethodArgType
;
argTypeMatchInt
:
MatchInt
|
null
;
}
export
default
function
useFormatFieldValue
({
argType
,
argTypeMatchInt
}:
Params
)
{
return
React
.
useCallback
((
value
:
string
|
undefined
)
=>
{
if
(
!
value
)
{
return
;
}
if
(
argTypeMatchInt
)
{
const
formattedString
=
value
.
replace
(
/
\s
/g
,
''
);
return
parseInt
(
formattedString
);
}
if
(
argType
===
'
bool
'
)
{
const
formattedValue
=
value
.
toLowerCase
();
switch
(
formattedValue
)
{
case
'
true
'
:
{
return
true
;
}
case
'
false
'
:{
return
false
;
}
default
:
return
value
;
}
}
return
value
;
},
[
argType
,
argTypeMatchInt
]);
}
ui/address/contract/methodForm/useValidateField.tsx
View file @
dfd590e5
...
@@ -4,7 +4,7 @@ import { getAddress, isAddress, isHex } from 'viem';
...
@@ -4,7 +4,7 @@ import { getAddress, isAddress, isHex } from 'viem';
import
type
{
SmartContractMethodArgType
}
from
'
types/api/contract
'
;
import
type
{
SmartContractMethodArgType
}
from
'
types/api/contract
'
;
import
type
{
MatchInt
}
from
'
./useArgTypeMatchInt
'
;
import
type
{
MatchInt
}
from
'
./useArgTypeMatchInt
'
;
import
{
BYTES_REGEXP
,
formatBooleanValue
}
from
'
./utils
'
;
import
{
BYTES_REGEXP
}
from
'
./utils
'
;
interface
Params
{
interface
Params
{
argType
:
SmartContractMethodArgType
;
argType
:
SmartContractMethodArgType
;
...
@@ -18,13 +18,15 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
...
@@ -18,13 +18,15 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
return
argType
.
match
(
BYTES_REGEXP
);
return
argType
.
match
(
BYTES_REGEXP
);
},
[
argType
]);
},
[
argType
]);
return
React
.
useCallback
((
value
:
string
|
undefined
)
=>
{
// some values are formatted before they are sent to the validator
if
(
!
value
)
{
// see ./useFormatFieldValue.tsx hook
return
React
.
useCallback
((
value
:
string
|
number
|
boolean
|
undefined
)
=>
{
if
(
value
===
undefined
||
value
===
''
)
{
return
isOptional
?
true
:
'
Field is required
'
;
return
isOptional
?
true
:
'
Field is required
'
;
}
}
if
(
argType
===
'
address
'
)
{
if
(
argType
===
'
address
'
)
{
if
(
!
isAddress
(
value
))
{
if
(
typeof
value
!==
'
string
'
||
!
isAddress
(
value
))
{
return
'
Invalid address format
'
;
return
'
Invalid address format
'
;
}
}
...
@@ -39,13 +41,11 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
...
@@ -39,13 +41,11 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
}
}
if
(
argTypeMatchInt
)
{
if
(
argTypeMatchInt
)
{
const
formattedValue
=
Number
(
value
.
replace
(
/
\s
/g
,
''
));
if
(
typeof
value
!==
'
number
'
||
Object
.
is
(
value
,
NaN
))
{
if
(
Object
.
is
(
formattedValue
,
NaN
))
{
return
'
Invalid integer format
'
;
return
'
Invalid integer format
'
;
}
}
if
(
formattedValue
>
argTypeMatchInt
.
max
||
formattedV
alue
<
argTypeMatchInt
.
min
)
{
if
(
value
>
argTypeMatchInt
.
max
||
v
alue
<
argTypeMatchInt
.
min
)
{
const
lowerBoundary
=
argTypeMatchInt
.
isUnsigned
?
'
0
'
:
`-1 * 2 ^
${
Number
(
argTypeMatchInt
.
power
)
-
1
}
`
;
const
lowerBoundary
=
argTypeMatchInt
.
isUnsigned
?
'
0
'
:
`-1 * 2 ^
${
Number
(
argTypeMatchInt
.
power
)
-
1
}
`
;
const
upperBoundary
=
argTypeMatchInt
.
isUnsigned
?
`2 ^
${
argTypeMatchInt
.
power
}
- 1`
:
`2 ^
${
Number
(
argTypeMatchInt
.
power
)
-
1
}
- 1`
;
const
upperBoundary
=
argTypeMatchInt
.
isUnsigned
?
`2 ^
${
argTypeMatchInt
.
power
}
- 1`
:
`2 ^
${
Number
(
argTypeMatchInt
.
power
)
-
1
}
- 1`
;
return
`Value should be in range from "
${
lowerBoundary
}
" to "
${
upperBoundary
}
" inclusively`
;
return
`Value should be in range from "
${
lowerBoundary
}
" to "
${
upperBoundary
}
" inclusively`
;
...
@@ -55,9 +55,8 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
...
@@ -55,9 +55,8 @@ export default function useValidateField({ isOptional, argType, argTypeMatchInt
}
}
if
(
argType
===
'
bool
'
)
{
if
(
argType
===
'
bool
'
)
{
const
formattedValue
=
formatBooleanValue
(
value
);
if
(
typeof
value
!==
'
boolean
'
)
{
if
(
formattedValue
===
undefined
)
{
return
'
Invalid boolean format. Allowed values: true, false
'
;
return
'
Invalid boolean format. Allowed values: 0, 1, true, false
'
;
}
}
}
}
...
...
ui/address/contract/methodForm/utils.ts
View file @
dfd590e5
...
@@ -17,25 +17,6 @@ export const getIntBoundaries = (power: number, isUnsigned: boolean) => {
...
@@ -17,25 +17,6 @@ export const getIntBoundaries = (power: number, isUnsigned: boolean) => {
return
[
min
,
max
];
return
[
min
,
max
];
};
};
export
const
formatBooleanValue
=
(
value
:
string
)
=>
{
const
formattedValue
=
value
.
toLowerCase
();
switch
(
formattedValue
)
{
case
'
true
'
:
case
'
1
'
:
{
return
'
true
'
;
}
case
'
false
'
:
case
'
0
'
:
{
return
'
false
'
;
}
default
:
return
;
}
};
export
function
transformFormDataToMethodArgs
(
formData
:
ContractMethodFormFields
)
{
export
function
transformFormDataToMethodArgs
(
formData
:
ContractMethodFormFields
)
{
const
result
:
Array
<
unknown
>
=
[];
const
result
:
Array
<
unknown
>
=
[];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment