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
95a83474
Commit
95a83474
authored
Mar 08, 2024
by
Max Alekseenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make solidityscan report component reusable
parent
f4f434d7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
199 additions
and
133 deletions
+199
-133
SolidityscanReport.tsx
ui/address/SolidityscanReport.tsx
+15
-133
SolidityscanReportButton.tsx
ui/shared/solidityscanReport/SolidityscanReportButton.tsx
+59
-0
SolidityscanReportDetails.tsx
ui/shared/solidityscanReport/SolidityscanReportDetails.tsx
+60
-0
SolidityscanReportScore.tsx
ui/shared/solidityscanReport/SolidityscanReportScore.tsx
+44
-0
useScoreLevelAndColor.ts
ui/shared/solidityscanReport/useScoreLevelAndColor.ts
+21
-0
No files found.
ui/address/SolidityscanReport.tsx
View file @
95a83474
import
{
import
{
Box
,
Text
,
chakra
}
from
'
@chakra-ui/react
'
;
Box
,
Flex
,
Text
,
Grid
,
Button
,
chakra
,
Popover
,
PopoverTrigger
,
PopoverBody
,
PopoverContent
,
useDisclosure
,
Skeleton
,
Center
,
useColorModeValue
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
SolidityscanReport
}
from
'
types/api/contract
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
SOLIDITYSCAN_REPORT
}
from
'
stubs/contract
'
;
import
{
SOLIDITYSCAN_REPORT
}
from
'
stubs/contract
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
LinkExternal
from
'
ui/shared/LinkExternal
'
;
import
LinkExternal
from
'
ui/shared/LinkExternal
'
;
import
SolidityscanReportButton
from
'
ui/shared/solidityscanReport/SolidityscanReportButton
'
;
type
DistributionItem
=
{
import
SolidityscanReportDetails
from
'
ui/shared/solidityscanReport/SolidityscanReportDetails
'
;
id
:
keyof
SolidityscanReport
[
'
scan_report
'
][
'
scan_summary
'
][
'
issue_severity_distribution
'
];
import
SolidityscanReportScore
from
'
ui/shared/solidityscanReport/SolidityscanReportScore
'
;
name
:
string
;
color
:
string
;
}
const
DISTRIBUTION_ITEMS
:
Array
<
DistributionItem
>
=
[
{
id
:
'
critical
'
,
name
:
'
Critical
'
,
color
:
'
#891F11
'
},
{
id
:
'
high
'
,
name
:
'
High
'
,
color
:
'
#EC672C
'
},
{
id
:
'
medium
'
,
name
:
'
Medium
'
,
color
:
'
#FBE74D
'
},
{
id
:
'
low
'
,
name
:
'
Low
'
,
color
:
'
#68C88E
'
},
{
id
:
'
informational
'
,
name
:
'
Informational
'
,
color
:
'
#A3AEBE
'
},
{
id
:
'
gas
'
,
name
:
'
Gas
'
,
color
:
'
#A47585
'
},
];
interface
Props
{
interface
Props
{
className
?:
string
;
className
?:
string
;
hash
:
string
;
hash
:
string
;
}
}
type
ItemProps
=
{
item
:
DistributionItem
;
vulnerabilities
:
SolidityscanReport
[
'
scan_report
'
][
'
scan_summary
'
][
'
issue_severity_distribution
'
];
vulnerabilitiesCount
:
number
;
}
const
SolidityScanReportItem
=
({
item
,
vulnerabilities
,
vulnerabilitiesCount
}:
ItemProps
)
=>
{
const
bgBar
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
const
yetAnotherGrayColor
=
useColorModeValue
(
'
gray.400
'
,
'
gray.500
'
);
return
(
<>
<
Box
w=
{
3
}
h=
{
3
}
bg=
{
item
.
color
}
borderRadius=
"6px"
mr=
{
2
}
></
Box
>
<
Flex
justifyContent=
"space-between"
mr=
{
3
}
>
<
Text
>
{
item
.
name
}
</
Text
>
<
Text
color=
{
vulnerabilities
[
item
.
id
]
>
0
?
'
text
'
:
yetAnotherGrayColor
}
>
{
vulnerabilities
[
item
.
id
]
}
</
Text
>
</
Flex
>
<
Box
bg=
{
bgBar
}
h=
"10px"
borderRadius=
"8px"
>
<
Box
bg=
{
item
.
color
}
w=
{
vulnerabilities
[
item
.
id
]
/
vulnerabilitiesCount
}
h=
"10px"
borderRadius=
"8px"
/>
</
Box
>
</>
);
};
const
SolidityscanReport
=
({
className
,
hash
}:
Props
)
=>
{
const
SolidityscanReport
=
({
className
,
hash
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
const
{
data
,
isPlaceholderData
,
isError
}
=
useApiQuery
(
'
contract_solidityscan_report
'
,
{
const
{
data
,
isPlaceholderData
,
isError
}
=
useApiQuery
(
'
contract_solidityscan_report
'
,
{
pathParams
:
{
hash
},
pathParams
:
{
hash
},
queryOptions
:
{
queryOptions
:
{
...
@@ -80,95 +24,33 @@ const SolidityscanReport = ({ className, hash }: Props) => {
...
@@ -80,95 +24,33 @@ const SolidityscanReport = ({ className, hash }: Props) => {
const
score
=
Number
(
data
?.
scan_report
.
scan_summary
.
score_v2
);
const
score
=
Number
(
data
?.
scan_report
.
scan_summary
.
score_v2
);
const
chartGrayColor
=
useColorModeValue
(
'
gray.100
'
,
'
gray.700
'
);
const
yetAnotherGrayColor
=
useColorModeValue
(
'
gray.400
'
,
'
gray.500
'
);
const
popoverBgColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
const
greatScoreColor
=
useColorModeValue
(
'
green.600
'
,
'
green.400
'
);
const
averageScoreColor
=
useColorModeValue
(
'
purple.600
'
,
'
purple.400
'
);
const
lowScoreColor
=
useColorModeValue
(
'
red.600
'
,
'
red.400
'
);
if
(
isError
||
!
score
)
{
if
(
isError
||
!
score
)
{
return
null
;
return
null
;
}
}
let
scoreColor
;
let
scoreLevel
;
if
(
score
>=
80
)
{
scoreColor
=
greatScoreColor
;
scoreLevel
=
'
GREAT
'
;
}
else
if
(
score
>=
30
)
{
scoreColor
=
averageScoreColor
;
scoreLevel
=
'
AVERAGE
'
;
}
else
{
scoreColor
=
lowScoreColor
;
scoreLevel
=
'
LOW
'
;
}
const
vulnerabilities
=
data
?.
scan_report
.
scan_summary
.
issue_severity_distribution
;
const
vulnerabilities
=
data
?.
scan_report
.
scan_summary
.
issue_severity_distribution
;
const
vulnerabilitiesCounts
=
vulnerabilities
?
Object
.
values
(
vulnerabilities
)
:
[];
const
vulnerabilitiesCounts
=
vulnerabilities
?
Object
.
values
(
vulnerabilities
)
:
[];
const
vulnerabilitiesCount
=
vulnerabilitiesCounts
.
reduce
((
acc
,
val
)
=>
acc
+
val
,
0
);
const
vulnerabilitiesCount
=
vulnerabilitiesCounts
.
reduce
((
acc
,
val
)
=>
acc
+
val
,
0
);
return
(
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
SolidityscanReportButton
<
PopoverTrigger
>
className=
{
className
}
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
borderRadius=
"base"
>
score=
{
score
}
<
Button
isLoading=
{
isPlaceholderData
}
className=
{
className
}
popoverContent=
{
(
color=
{
scoreColor
}
<>
size=
"sm"
variant=
"outline"
colorScheme=
"gray"
onClick=
{
onToggle
}
aria
-
label=
"SolidityScan score"
fontWeight=
{
500
}
px=
"6px"
h=
"32px"
flexShrink=
{
0
}
>
<
IconSvg
name=
{
score
<
80
?
'
score/score-not-ok
'
:
'
score/score-ok
'
}
boxSize=
{
5
}
mr=
{
1
}
/>
{
score
}
</
Button
>
</
Skeleton
>
</
PopoverTrigger
>
<
PopoverContent
w=
{
{
base
:
'
100vw
'
,
lg
:
'
328px
'
}
}
>
<
PopoverBody
px=
"26px"
py=
"20px"
fontSize=
"sm"
>
<
Box
mb=
{
5
}
>
Contract analyzed for 140+ vulnerability patterns by SolidityScan
</
Box
>
<
Box
mb=
{
5
}
>
Contract analyzed for 140+ vulnerability patterns by SolidityScan
</
Box
>
<
Flex
alignItems=
"center"
mb=
{
5
}
>
<
SolidityscanReportScore
score=
{
score
}
/>
<
Box
w=
{
12
}
h=
{
12
}
bgGradient=
{
`conic-gradient(${ scoreColor } 0, ${ scoreColor } ${ score }%, ${ chartGrayColor } 0, ${ chartGrayColor } 100%)`
}
borderRadius=
"24px"
position=
"relative"
mr=
{
3
}
>
<
Center
position=
"absolute"
w=
"38px"
h=
"38px"
top=
"5px"
right=
"5px"
bg=
{
popoverBgColor
}
borderRadius=
"20px"
>
<
IconSvg
name=
{
score
<
80
?
'
score/score-not-ok
'
:
'
score/score-ok
'
}
boxSize=
{
5
}
color=
{
scoreColor
}
/>
</
Center
>
</
Box
>
<
Box
>
<
Flex
>
<
Text
color=
{
scoreColor
}
fontSize=
"lg"
fontWeight=
{
500
}
>
{
score
}
</
Text
>
<
Text
color=
{
yetAnotherGrayColor
}
fontSize=
"lg"
fontWeight=
{
500
}
whiteSpace=
"pre"
>
/ 100
</
Text
>
</
Flex
>
<
Text
color=
{
scoreColor
}
fontWeight=
{
500
}
>
Security score is
{
scoreLevel
}
</
Text
>
</
Box
>
</
Flex
>
{
vulnerabilities
&&
vulnerabilitiesCount
>
0
&&
(
{
vulnerabilities
&&
vulnerabilitiesCount
>
0
&&
(
<
Box
mb=
{
5
}
>
<
Box
mb=
{
5
}
>
<
Text
py=
"7px"
variant=
"secondary"
fontSize=
"xs"
fontWeight=
{
500
}
>
Vulnerabilities distribution
</
Text
>
<
Text
py=
"7px"
variant=
"secondary"
fontSize=
"xs"
fontWeight=
{
500
}
>
Vulnerabilities distribution
</
Text
>
<
Grid
templateColumns=
"20px 1fr 100px"
alignItems=
"center"
rowGap=
{
2
}
>
<
SolidityscanReportDetails
vulnerabilities=
{
vulnerabilities
}
vulnerabilitiesCount=
{
vulnerabilitiesCount
}
/>
{
DISTRIBUTION_ITEMS
.
map
(
item
=>
(
<
SolidityScanReportItem
item=
{
item
}
key=
{
item
.
id
}
vulnerabilities=
{
vulnerabilities
}
vulnerabilitiesCount=
{
vulnerabilitiesCount
}
/>
))
}
</
Grid
>
</
Box
>
</
Box
>
)
}
)
}
<
LinkExternal
href=
{
data
?.
scan_report
.
scanner_reference_url
}
>
View full report
</
LinkExternal
>
<
LinkExternal
href=
{
data
?.
scan_report
.
scanner_reference_url
}
>
View full report
</
LinkExternal
>
</
PopoverBody
>
</>
</
PopoverContent
>
)
}
</
Popover
>
/
>
);
);
};
};
...
...
ui/shared/solidityscanReport/SolidityscanReportButton.tsx
0 → 100644
View file @
95a83474
import
{
Button
,
chakra
,
Popover
,
PopoverTrigger
,
PopoverBody
,
PopoverContent
,
useDisclosure
,
Skeleton
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
useScoreLevelAndColor
from
'
./useScoreLevelAndColor
'
;
interface
Props
{
className
?:
string
;
score
:
number
;
popoverContent
?:
React
.
ReactNode
;
isLoading
?:
boolean
;
}
const
SolidityscanReportButton
=
({
className
,
score
,
popoverContent
,
isLoading
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
const
{
scoreColor
}
=
useScoreLevelAndColor
(
score
);
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
PopoverTrigger
>
<
Skeleton
isLoaded=
{
!
isLoading
}
borderRadius=
"base"
>
<
Button
className=
{
className
}
color=
{
scoreColor
}
size=
"sm"
variant=
"outline"
colorScheme=
"gray"
onClick=
{
onToggle
}
aria
-
label=
"SolidityScan score"
fontWeight=
{
500
}
px=
"6px"
h=
"32px"
flexShrink=
{
0
}
>
<
IconSvg
name=
{
score
<
80
?
'
score/score-not-ok
'
:
'
score/score-ok
'
}
boxSize=
{
5
}
mr=
{
1
}
/>
{
score
}
</
Button
>
</
Skeleton
>
</
PopoverTrigger
>
<
PopoverContent
w=
{
{
base
:
'
100vw
'
,
lg
:
'
328px
'
}
}
>
<
PopoverBody
px=
"26px"
py=
"20px"
fontSize=
"sm"
>
{
popoverContent
}
</
PopoverBody
>
</
PopoverContent
>
</
Popover
>
);
};
export
default
chakra
(
SolidityscanReportButton
);
ui/shared/solidityscanReport/SolidityscanReportDetails.tsx
0 → 100644
View file @
95a83474
import
{
Box
,
Flex
,
Text
,
Grid
,
useColorModeValue
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
SolidityscanReport
}
from
'
types/api/contract
'
;
type
DistributionItem
=
{
id
:
keyof
SolidityscanReport
[
'
scan_report
'
][
'
scan_summary
'
][
'
issue_severity_distribution
'
];
name
:
string
;
color
:
string
;
}
const
DISTRIBUTION_ITEMS
:
Array
<
DistributionItem
>
=
[
{
id
:
'
critical
'
,
name
:
'
Critical
'
,
color
:
'
#891F11
'
},
{
id
:
'
high
'
,
name
:
'
High
'
,
color
:
'
#EC672C
'
},
{
id
:
'
medium
'
,
name
:
'
Medium
'
,
color
:
'
#FBE74D
'
},
{
id
:
'
low
'
,
name
:
'
Low
'
,
color
:
'
#68C88E
'
},
{
id
:
'
informational
'
,
name
:
'
Informational
'
,
color
:
'
#A3AEBE
'
},
{
id
:
'
gas
'
,
name
:
'
Gas
'
,
color
:
'
#A47585
'
},
];
interface
Props
{
vulnerabilities
:
SolidityscanReport
[
'
scan_report
'
][
'
scan_summary
'
][
'
issue_severity_distribution
'
];
vulnerabilitiesCount
:
number
;
}
type
ItemProps
=
{
item
:
DistributionItem
;
vulnerabilities
:
SolidityscanReport
[
'
scan_report
'
][
'
scan_summary
'
][
'
issue_severity_distribution
'
];
vulnerabilitiesCount
:
number
;
}
const
SolidityScanReportItem
=
({
item
,
vulnerabilities
,
vulnerabilitiesCount
}:
ItemProps
)
=>
{
const
bgBar
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
const
yetAnotherGrayColor
=
useColorModeValue
(
'
gray.400
'
,
'
gray.500
'
);
return
(
<>
<
Box
w=
{
3
}
h=
{
3
}
bg=
{
item
.
color
}
borderRadius=
"6px"
mr=
{
2
}
></
Box
>
<
Flex
justifyContent=
"space-between"
mr=
{
3
}
>
<
Text
>
{
item
.
name
}
</
Text
>
<
Text
color=
{
vulnerabilities
[
item
.
id
]
>
0
?
'
text
'
:
yetAnotherGrayColor
}
>
{
vulnerabilities
[
item
.
id
]
}
</
Text
>
</
Flex
>
<
Box
bg=
{
bgBar
}
h=
"10px"
borderRadius=
"8px"
>
<
Box
bg=
{
item
.
color
}
w=
{
vulnerabilities
[
item
.
id
]
/
vulnerabilitiesCount
}
h=
"10px"
borderRadius=
"8px"
/>
</
Box
>
</>
);
};
const
SolidityscanReportDetails
=
({
vulnerabilities
,
vulnerabilitiesCount
}:
Props
)
=>
{
return
(
<
Grid
templateColumns=
"20px 1fr 100px"
alignItems=
"center"
rowGap=
{
2
}
>
{
DISTRIBUTION_ITEMS
.
map
(
item
=>
(
<
SolidityScanReportItem
item=
{
item
}
key=
{
item
.
id
}
vulnerabilities=
{
vulnerabilities
}
vulnerabilitiesCount=
{
vulnerabilitiesCount
}
/>
))
}
</
Grid
>
);
};
export
default
chakra
(
SolidityscanReportDetails
);
ui/shared/solidityscanReport/SolidityscanReportScore.tsx
0 → 100644
View file @
95a83474
import
{
Box
,
Flex
,
Text
,
chakra
,
Center
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
useScoreLevelAndColor
from
'
./useScoreLevelAndColor
'
;
interface
Props
{
score
:
number
;
}
const
SolidityscanReportScore
=
({
score
}:
Props
)
=>
{
const
{
scoreLevel
,
scoreColor
}
=
useScoreLevelAndColor
(
score
);
const
chartGrayColor
=
useColorModeValue
(
'
gray.100
'
,
'
gray.700
'
);
const
yetAnotherGrayColor
=
useColorModeValue
(
'
gray.400
'
,
'
gray.500
'
);
const
popoverBgColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
return
(
<
Flex
alignItems=
"center"
mb=
{
5
}
>
<
Box
w=
{
12
}
h=
{
12
}
bgGradient=
{
`conic-gradient(${ scoreColor } 0, ${ scoreColor } ${ score }%, ${ chartGrayColor } 0, ${ chartGrayColor } 100%)`
}
borderRadius=
"24px"
position=
"relative"
mr=
{
3
}
>
<
Center
position=
"absolute"
w=
"38px"
h=
"38px"
top=
"5px"
right=
"5px"
bg=
{
popoverBgColor
}
borderRadius=
"20px"
>
<
IconSvg
name=
{
score
<
80
?
'
score/score-not-ok
'
:
'
score/score-ok
'
}
boxSize=
{
5
}
color=
{
scoreColor
}
/>
</
Center
>
</
Box
>
<
Box
>
<
Flex
>
<
Text
color=
{
scoreColor
}
fontSize=
"lg"
fontWeight=
{
500
}
>
{
score
}
</
Text
>
<
Text
color=
{
yetAnotherGrayColor
}
fontSize=
"lg"
fontWeight=
{
500
}
whiteSpace=
"pre"
>
/ 100
</
Text
>
</
Flex
>
<
Text
color=
{
scoreColor
}
fontWeight=
{
500
}
>
Security score is
{
scoreLevel
}
</
Text
>
</
Box
>
</
Flex
>
);
};
export
default
chakra
(
SolidityscanReportScore
);
ui/shared/solidityscanReport/useScoreLevelAndColor.ts
0 → 100644
View file @
95a83474
import
{
useColorModeValue
}
from
'
@chakra-ui/react
'
;
export
default
function
useScoreLevelAndColor
(
score
:
number
)
{
const
greatScoreColor
=
useColorModeValue
(
'
green.600
'
,
'
green.400
'
);
const
averageScoreColor
=
useColorModeValue
(
'
purple.600
'
,
'
purple.400
'
);
const
lowScoreColor
=
useColorModeValue
(
'
red.600
'
,
'
red.400
'
);
let
scoreColor
;
let
scoreLevel
;
if
(
score
>=
80
)
{
scoreColor
=
greatScoreColor
;
scoreLevel
=
'
GREAT
'
;
}
else
if
(
score
>=
30
)
{
scoreColor
=
averageScoreColor
;
scoreLevel
=
'
AVERAGE
'
;
}
else
{
scoreColor
=
lowScoreColor
;
scoreLevel
=
'
LOW
'
;
}
return
{
scoreColor
,
scoreLevel
};
}
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