From 0d38f55674b0d0c55d6a9079a8a2540cbcacd57d Mon Sep 17 00:00:00 2001 From: Mathieu Suen Date: Fri, 4 Oct 2024 15:32:24 +0200 Subject: [PATCH] SGB-149 Fix hotspot page when component is not yet fetch --- .../security-hotspots/SecurityHotspotsApp.tsx | 41 ++++++++++++++----- .../SecurityHotspotsAppRenderer.tsx | 9 ++-- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx index d00d9e9154c..39c4bd0a580 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx @@ -54,7 +54,7 @@ const PAGE_SIZE = 500; interface Props { branchLike?: BranchLike; - component: Component; + component?: Component; currentUser: CurrentUser; location: Location; router: Router; @@ -124,7 +124,8 @@ export class SecurityHotspotsApp extends React.PureComponent { componentDidUpdate(previous: Props) { if ( !isSameBranchLike(previous.branchLike, this.props.branchLike) || - this.props.component.key !== previous.component.key || + (this.props.component !== undefined && + this.props.component.key !== previous.component?.key) || this.props.location.query.hotspots !== previous.location.query.hotspots || SECURITY_STANDARDS.some((s) => this.props.location.query[s] !== previous.location.query[s]) || this.props.location.query.files !== previous.location.query.files @@ -276,11 +277,13 @@ export class SecurityHotspotsApp extends React.PureComponent { this.fetchSecurityHotspots(), this.fetchSecurityHotspotsReviewed(), ]) - .then(([standards, { hotspots, paging }]) => { - if (!this.mounted) { + .then(([standards, components]) => { + if (!this.mounted || components === undefined) { return; } + const { hotspots, paging } = components; + const { branchLike } = this.props; if (isSameBranchLike(previousBranch, branchLike)) { @@ -308,6 +311,10 @@ export class SecurityHotspotsApp extends React.PureComponent { this.setState({ loadingMeasure: true }); + if (component === undefined) { + return Promise.resolve(); + } + return getMeasures({ component: component.key, metricKeys: reviewedHotspotsMetricKey, @@ -355,6 +362,9 @@ export class SecurityHotspotsApp extends React.PureComponent { }) { const { branchLike, component, location } = this.props; const { filters } = this.state; + if (component === undefined) { + return Promise.resolve(undefined); + } const hotspotFilters: Dict = {}; @@ -390,6 +400,10 @@ export class SecurityHotspotsApp extends React.PureComponent { const { branchLike, component, location } = this.props; const { filters } = this.state; + if (component === undefined) { + return Promise.resolve(undefined); + } + const hotspotKeys = location.query.hotspots ? (location.query.hotspots as string).split(',') : undefined; @@ -457,11 +471,13 @@ export class SecurityHotspotsApp extends React.PureComponent { this.setState({ loading: true }); return this.fetchSecurityHotspots() - .then(({ hotspots, paging }) => { - if (!this.mounted) { + .then((components) => { + if (!this.mounted || components === undefined) { return; } + const { hotspots, paging } = components; + this.setState({ hotspots, hotspotsPageIndex: 1, @@ -487,6 +503,9 @@ export class SecurityHotspotsApp extends React.PureComponent { }; handleShowAllHotspots = () => { + if (this.props.component === undefined) { + return; + } this.props.router.push({ pathname: this.props.location.pathname, query: { @@ -518,8 +537,7 @@ export class SecurityHotspotsApp extends React.PureComponent { ) .then((hotspotPages) => { const allHotspots = flatMap(hotspotPages, 'hotspots'); - - const { paging } = hotspotPages[hotspotPages.length - 1]; + const { paging } = hotspotPages[hotspotPages.length - 1]!; const nextHotspot = allHotspots[Math.min(index, allHotspots.length - 1)]; @@ -539,11 +557,13 @@ export class SecurityHotspotsApp extends React.PureComponent { this.setState({ loadingMore: true }); return this.fetchSecurityHotspots(hotspotPages + 1) - .then(({ hotspots: additionalHotspots }) => { - if (!this.mounted) { + .then((components) => { + if (!this.mounted || components === undefined) { return; } + const { hotspots: additionalHotspots } = components; + this.setState({ hotspots: [...hotspots, ...additionalHotspots], hotspotsPageIndex: hotspotPages + 1, @@ -630,6 +650,7 @@ export default withRouter( withIndexationGuard({ Component: SecurityHotspotsApp, showIndexationMessage: ({ component }) => + component !== undefined && !!(component.qualifier === ComponentQualifier.Application && component.needIssueSync), }), ), diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx index 9d64bf4a634..921187e0374 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx @@ -53,7 +53,7 @@ import HotspotViewer from './components/HotspotViewer'; export interface SecurityHotspotsAppRendererProps { branchLike?: BranchLike; - component: Component; + component?: Component; filterByCWE?: string; filterByCategory?: { category: string; @@ -106,10 +106,13 @@ export default function SecurityHotspotsAppRenderer(props: SecurityHotspotsAppRe standards, } = props; - const isProject = component.qualifier === ComponentQualifier.Project; - const { top: topScroll } = useFollowScroll(); + if (component === undefined) { + return null; + } + + const isProject = component.qualifier === ComponentQualifier.Project; const distanceFromBottom = topScroll + window.innerHeight - document.body.clientHeight; const footerVisibleHeight = -- 2.39.5