Commit b77d0331 authored by Max Alekseenko's avatar Max Alekseenko

add reports to apps inside hook

parent 8c974a46
...@@ -22,6 +22,7 @@ export type MarketplaceAppOverview = MarketplaceAppPreview & MarketplaceAppSocia ...@@ -22,6 +22,7 @@ export type MarketplaceAppOverview = MarketplaceAppPreview & MarketplaceAppSocia
author: string; author: string;
description: string; description: string;
site?: string; site?: string;
securityReport?: any; // eslint-disable-line @typescript-eslint/no-explicit-any
} }
export enum MarketplaceCategory { export enum MarketplaceCategory {
......
...@@ -2,10 +2,9 @@ import { Hide, Show } from '@chakra-ui/react'; ...@@ -2,10 +2,9 @@ import { Hide, Show } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import type { MarketplaceAppPreview, ContractListTypes } from 'types/client/marketplace'; import type { MarketplaceAppOverview, ContractListTypes } from 'types/client/marketplace';
import { MarketplaceCategory } from 'types/client/marketplace'; import { MarketplaceCategory } from 'types/client/marketplace';
import config from 'configs/app';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import DataListDisplay from 'ui/shared/DataListDisplay'; import DataListDisplay from 'ui/shared/DataListDisplay';
import EmptySearchResult from 'ui/shared/EmptySearchResult'; import EmptySearchResult from 'ui/shared/EmptySearchResult';
...@@ -15,14 +14,13 @@ import ListItem from './MarketplaceListWithScores/ListItem'; ...@@ -15,14 +14,13 @@ import ListItem from './MarketplaceListWithScores/ListItem';
import Table from './MarketplaceListWithScores/Table'; import Table from './MarketplaceListWithScores/Table';
interface Props { interface Props {
apps: Array<MarketplaceAppPreview>; apps: Array<MarketplaceAppOverview>;
showAppInfo: (id: string) => void; showAppInfo: (id: string) => void;
favoriteApps: Array<string>; favoriteApps: Array<string>;
onFavoriteClick: (id: string, isFavorite: boolean) => void; onFavoriteClick: (id: string, isFavorite: boolean) => void;
isLoading: boolean; isLoading: boolean;
selectedCategoryId?: string; selectedCategoryId?: string;
onAppClick: (event: MouseEvent, id: string) => void; onAppClick: (event: MouseEvent, id: string) => void;
securityReports: Array<any> | undefined; // eslint-disable-line @typescript-eslint/no-explicit-any
showContractList: (id: string, type: ContractListTypes) => void; showContractList: (id: string, type: ContractListTypes) => void;
} }
...@@ -34,24 +32,14 @@ const MarketplaceListWithScores = ({ ...@@ -34,24 +32,14 @@ const MarketplaceListWithScores = ({
isLoading, isLoading,
selectedCategoryId, selectedCategoryId,
onAppClick, onAppClick,
securityReports = [],
showContractList, showContractList,
}: Props) => { }: Props) => {
const displayedApps = React.useMemo(() => const displayedApps = React.useMemo(() =>
apps apps
.map((app) => {
const securityReport = securityReports.find(item => item.appName === app.id)?.chainsData[config.chain.name?.toLowerCase() || ''];
if (securityReport) {
const issues: Record<string, number> = securityReport.overallInfo.issueSeverityDistribution;
securityReport.overallInfo.totalIssues = Object.values(issues).reduce((acc, val) => acc + val, 0);
securityReport.overallInfo.securityScore = Number(securityReport.overallInfo.securityScore.toFixed(2));
}
return { ...app, securityReport };
})
.filter((app) => app.securityReport) .filter((app) => app.securityReport)
.sort((a, b) => b.securityReport.overallInfo.securityScore - a.securityReport.overallInfo.securityScore) .sort((a, b) => b.securityReport.overallInfo.securityScore - a.securityReport.overallInfo.securityScore)
, [ apps, securityReports ]); , [ apps ]);
const content = apps.length > 0 ? ( const content = apps.length > 0 ? (
<> <>
......
...@@ -10,6 +10,8 @@ import useApiFetch from 'lib/api/useApiFetch'; ...@@ -10,6 +10,8 @@ import useApiFetch from 'lib/api/useApiFetch';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import { MARKETPLACE_APP } from 'stubs/marketplace'; import { MARKETPLACE_APP } from 'stubs/marketplace';
import useSecurityReports from './useSecurityReports';
const feature = config.features.marketplace; const feature = config.features.marketplace;
function isAppNameMatches(q: string, app: MarketplaceAppOverview) { function isAppNameMatches(q: string, app: MarketplaceAppOverview) {
...@@ -56,6 +58,8 @@ export default function useMarketplaceApps( ...@@ -56,6 +58,8 @@ export default function useMarketplaceApps(
const fetch = useFetch(); const fetch = useFetch();
const apiFetch = useApiFetch(); const apiFetch = useApiFetch();
const { data: securityReports, isPlaceholderData: isSecurityReportsPlaceholderData } = useSecurityReports();
// Update favorite apps only when selectedCategoryId changes to avoid sortApps to be called on each favorite app click // Update favorite apps only when selectedCategoryId changes to avoid sortApps to be called on each favorite app click
const lastFavoriteAppsRef = React.useRef(favoriteApps); const lastFavoriteAppsRef = React.useRef(favoriteApps);
React.useEffect(() => { React.useEffect(() => {
...@@ -79,21 +83,37 @@ export default function useMarketplaceApps( ...@@ -79,21 +83,37 @@ export default function useMarketplaceApps(
enabled: feature.isEnabled, enabled: feature.isEnabled,
}); });
const appsWithSecurityReports = React.useMemo(() => {
if (!securityReports && !isSecurityReportsPlaceholderData) {
return data;
}
return data?.map((app) => {
const securityReport = securityReports?.find(item => item.appName === app.id)?.chainsData[config.chain.name?.toLowerCase() || ''];
if (securityReport) {
const issues: Record<string, number> = securityReport.overallInfo.issueSeverityDistribution;
securityReport.overallInfo.totalIssues = Object.values(issues).reduce((acc, val) => acc + val, 0);
securityReport.overallInfo.securityScore = Number(securityReport.overallInfo.securityScore.toFixed(2));
}
return { ...app, securityReport };
});
}, [ data, securityReports, isSecurityReportsPlaceholderData ]);
const displayedApps = React.useMemo(() => { const displayedApps = React.useMemo(() => {
return data?.filter(app => isAppNameMatches(filter, app) && isAppCategoryMatches(selectedCategoryId, app, favoriteApps)) || []; return appsWithSecurityReports?.filter(app => isAppNameMatches(filter, app) && isAppCategoryMatches(selectedCategoryId, app, favoriteApps)) || [];
}, [ selectedCategoryId, data, filter, favoriteApps ]); }, [ selectedCategoryId, appsWithSecurityReports, filter, favoriteApps ]);
return React.useMemo(() => ({ return React.useMemo(() => ({
data, data,
displayedApps, displayedApps,
error, error,
isError, isError,
isPlaceholderData, isPlaceholderData: isPlaceholderData || isSecurityReportsPlaceholderData,
}), [ }), [
data, data,
displayedApps, displayedApps,
error, error,
isError, isError,
isPlaceholderData, isPlaceholderData,
isSecurityReportsPlaceholderData,
]); ]);
} }
...@@ -25,7 +25,6 @@ import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton'; ...@@ -25,7 +25,6 @@ import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
import TabsWithScroll from 'ui/shared/Tabs/TabsWithScroll'; import TabsWithScroll from 'ui/shared/Tabs/TabsWithScroll';
import useMarketplace from '../marketplace/useMarketplace'; import useMarketplace from '../marketplace/useMarketplace';
import useSecurityReports from '../marketplace/useSecurityReports';
const feature = config.features.marketplace; const feature = config.features.marketplace;
const links: Array<{ label: string; href: string; icon: IconName }> = []; const links: Array<{ label: string; href: string; icon: IconName }> = [];
...@@ -73,11 +72,6 @@ const Marketplace = () => { ...@@ -73,11 +72,6 @@ const Marketplace = () => {
contractListModalType, contractListModalType,
} = useMarketplace(); } = useMarketplace();
const {
data: securityReports,
isPlaceholderData: isSecurityReportsPlaceholderData,
} = useSecurityReports();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const categoryTabs = React.useMemo(() => { const categoryTabs = React.useMemo(() => {
...@@ -137,10 +131,6 @@ const Marketplace = () => { ...@@ -137,10 +131,6 @@ const Marketplace = () => {
} }
const selectedApp = displayedApps.find(app => app.id === selectedAppId); const selectedApp = displayedApps.find(app => app.id === selectedAppId);
const selectedAppContractList = securityReports
?.find(item => item.appName === selectedAppId)
?.chainsData[config.chain.name?.toLowerCase() || '']
?.contractsData;
return ( return (
<> <>
...@@ -242,10 +232,9 @@ const Marketplace = () => { ...@@ -242,10 +232,9 @@ const Marketplace = () => {
showAppInfo={ showAppInfo } showAppInfo={ showAppInfo }
favoriteApps={ favoriteApps } favoriteApps={ favoriteApps }
onFavoriteClick={ onFavoriteClick } onFavoriteClick={ onFavoriteClick }
isLoading={ isPlaceholderData || isSecurityReportsPlaceholderData } isLoading={ isPlaceholderData }
selectedCategoryId={ selectedCategoryId } selectedCategoryId={ selectedCategoryId }
onAppClick={ handleAppClick } onAppClick={ handleAppClick }
securityReports={ securityReports }
showContractList={ showContractList } showContractList={ showContractList }
/> />
) : ( ) : (
...@@ -280,7 +269,7 @@ const Marketplace = () => { ...@@ -280,7 +269,7 @@ const Marketplace = () => {
{ (selectedApp && contractListModalType) && ( { (selectedApp && contractListModalType) && (
<ContractListModal <ContractListModal
type={ contractListModalType } type={ contractListModalType }
contracts={ selectedAppContractList } contracts={ selectedApp?.securityReport?.contractsData }
onClose={ clearSelectedAppId } onClose={ clearSelectedAppId }
/> />
) } ) }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment