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
author: string;
description: string;
site?: string;
securityReport?: any; // eslint-disable-line @typescript-eslint/no-explicit-any
}
export enum MarketplaceCategory {
......
......@@ -2,10 +2,9 @@ import { Hide, Show } from '@chakra-ui/react';
import React 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 config from 'configs/app';
import { apos } from 'lib/html-entities';
import DataListDisplay from 'ui/shared/DataListDisplay';
import EmptySearchResult from 'ui/shared/EmptySearchResult';
......@@ -15,14 +14,13 @@ import ListItem from './MarketplaceListWithScores/ListItem';
import Table from './MarketplaceListWithScores/Table';
interface Props {
apps: Array<MarketplaceAppPreview>;
apps: Array<MarketplaceAppOverview>;
showAppInfo: (id: string) => void;
favoriteApps: Array<string>;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
isLoading: boolean;
selectedCategoryId?: string;
onAppClick: (event: MouseEvent, id: string) => void;
securityReports: Array<any> | undefined; // eslint-disable-line @typescript-eslint/no-explicit-any
showContractList: (id: string, type: ContractListTypes) => void;
}
......@@ -34,24 +32,14 @@ const MarketplaceListWithScores = ({
isLoading,
selectedCategoryId,
onAppClick,
securityReports = [],
showContractList,
}: Props) => {
const displayedApps = React.useMemo(() =>
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)
.sort((a, b) => b.securityReport.overallInfo.securityScore - a.securityReport.overallInfo.securityScore)
, [ apps, securityReports ]);
, [ apps ]);
const content = apps.length > 0 ? (
<>
......
......@@ -10,6 +10,8 @@ import useApiFetch from 'lib/api/useApiFetch';
import useFetch from 'lib/hooks/useFetch';
import { MARKETPLACE_APP } from 'stubs/marketplace';
import useSecurityReports from './useSecurityReports';
const feature = config.features.marketplace;
function isAppNameMatches(q: string, app: MarketplaceAppOverview) {
......@@ -56,6 +58,8 @@ export default function useMarketplaceApps(
const fetch = useFetch();
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
const lastFavoriteAppsRef = React.useRef(favoriteApps);
React.useEffect(() => {
......@@ -79,21 +83,37 @@ export default function useMarketplaceApps(
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(() => {
return data?.filter(app => isAppNameMatches(filter, app) && isAppCategoryMatches(selectedCategoryId, app, favoriteApps)) || [];
}, [ selectedCategoryId, data, filter, favoriteApps ]);
return appsWithSecurityReports?.filter(app => isAppNameMatches(filter, app) && isAppCategoryMatches(selectedCategoryId, app, favoriteApps)) || [];
}, [ selectedCategoryId, appsWithSecurityReports, filter, favoriteApps ]);
return React.useMemo(() => ({
data,
displayedApps,
error,
isError,
isPlaceholderData,
isPlaceholderData: isPlaceholderData || isSecurityReportsPlaceholderData,
}), [
data,
displayedApps,
error,
isError,
isPlaceholderData,
isSecurityReportsPlaceholderData,
]);
}
......@@ -25,7 +25,6 @@ import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
import TabsWithScroll from 'ui/shared/Tabs/TabsWithScroll';
import useMarketplace from '../marketplace/useMarketplace';
import useSecurityReports from '../marketplace/useSecurityReports';
const feature = config.features.marketplace;
const links: Array<{ label: string; href: string; icon: IconName }> = [];
......@@ -73,11 +72,6 @@ const Marketplace = () => {
contractListModalType,
} = useMarketplace();
const {
data: securityReports,
isPlaceholderData: isSecurityReportsPlaceholderData,
} = useSecurityReports();
const isMobile = useIsMobile();
const categoryTabs = React.useMemo(() => {
......@@ -137,10 +131,6 @@ const Marketplace = () => {
}
const selectedApp = displayedApps.find(app => app.id === selectedAppId);
const selectedAppContractList = securityReports
?.find(item => item.appName === selectedAppId)
?.chainsData[config.chain.name?.toLowerCase() || '']
?.contractsData;
return (
<>
......@@ -242,10 +232,9 @@ const Marketplace = () => {
showAppInfo={ showAppInfo }
favoriteApps={ favoriteApps }
onFavoriteClick={ onFavoriteClick }
isLoading={ isPlaceholderData || isSecurityReportsPlaceholderData }
isLoading={ isPlaceholderData }
selectedCategoryId={ selectedCategoryId }
onAppClick={ handleAppClick }
securityReports={ securityReports }
showContractList={ showContractList }
/>
) : (
......@@ -280,7 +269,7 @@ const Marketplace = () => {
{ (selectedApp && contractListModalType) && (
<ContractListModal
type={ contractListModalType }
contracts={ selectedAppContractList }
contracts={ selectedApp?.securityReport?.contractsData }
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