]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20057 Security hostpot header remains visible
authorDavid Cho-Lerat <david.cho-lerat@sonarsource.com>
Thu, 31 Aug 2023 08:56:43 +0000 (10:56 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 31 Aug 2023 20:02:56 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx

index 3752781483a1c5f6a97c3632e07c47cf429973d9..56e20a3c899a747601cab119b2b7369c3697a7a7 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+
 import { withTheme } from '@emotion/react';
 import styled from '@emotion/styled';
 import {
@@ -47,6 +48,7 @@ import { SecurityStandard, Standards } from '../../../types/security';
 import { Hotspot, HotspotStatusOption } from '../../../types/security-hotspots';
 import { Component } from '../../../types/types';
 import HotspotHeaderRightSection from './HotspotHeaderRightSection';
+import HotspotSnippetHeader from './HotspotSnippetHeader';
 import Status from './status/Status';
 import StatusReviewButton from './status/StatusReviewButton';
 
@@ -54,6 +56,7 @@ export interface HotspotHeaderProps {
   hotspot: Hotspot;
   component: Component;
   branchLike?: BranchLike;
+  isCodeTab?: boolean;
   standards?: Standards;
   onUpdateHotspot: (statusUpdate?: boolean, statusOption?: HotspotStatusOption) => Promise<void>;
   tabs: React.ReactNode;
@@ -67,7 +70,8 @@ interface StyledHeaderProps {
 }
 
 export function HotspotHeader(props: HotspotHeaderProps) {
-  const { hotspot, component, branchLike, standards, tabs, isCompressed, isScrolled } = props;
+  const { branchLike, component, hotspot, isCodeTab, isCompressed, isScrolled, standards, tabs } =
+    props;
   const { message, messageFormattings, rule, key } = hotspot;
   const refrechBranchStatus = useRefreshBranchStatus();
 
@@ -86,10 +90,17 @@ export function HotspotHeader(props: HotspotHeaderProps) {
   };
 
   const content = isCompressed ? (
-    <div className="sw-flex sw-justify-between">
-      {tabs}
-      <StatusReviewButton hotspot={hotspot} onStatusChange={handleStatusChange} />
-    </div>
+    <span>
+      <div className="sw-flex sw-justify-between">
+        {tabs}
+
+        <StatusReviewButton hotspot={hotspot} onStatusChange={handleStatusChange} />
+      </div>
+
+      {isCodeTab && (
+        <HotspotSnippetHeader hotspot={hotspot} component={component} branchLike={branchLike} />
+      )}
+    </span>
   ) : (
     <>
       <div className="sw-flex sw-justify-between sw-gap-8 sw-mb-4">
@@ -124,6 +135,10 @@ export function HotspotHeader(props: HotspotHeaderProps) {
         </div>
       </div>
       {tabs}
+
+      {isCodeTab && (
+        <HotspotSnippetHeader hotspot={hotspot} component={component} branchLike={branchLike} />
+      )}
     </>
   );
 
index 285bdd7c94a2d2235d9e84245dcd3599a4690c13..95a5aee9e1032c3444f0535fb8ef4b28c1de48d9 100644 (file)
@@ -197,7 +197,7 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
   };
 
   render() {
-    const { branchLike, component, hotspot, selectedHotspotLocation } = this.props;
+    const { hotspot, selectedHotspotLocation } = this.props;
     const { highlightedSymbols, lastLine, loading, sourceLines, secondaryLocations } = this.state;
 
     const locations = locationsByLine([hotspot]);
@@ -206,8 +206,6 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
 
     return (
       <HotspotSnippetContainerRenderer
-        branchLike={branchLike}
-        component={component}
         highlightedSymbols={highlightedSymbols}
         hotspot={hotspot}
         loading={loading}
index 92abb4afe39d5c056d06024e6d9f26e38c428987..0beaee81aa654480a309d87c86ec07bd5d935487 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+
 import { withTheme } from '@emotion/react';
 import styled from '@emotion/styled';
 import { themeBorder, themeColor } from 'design-system';
 import * as React from 'react';
 import Spinner from '../../../components/ui/Spinner';
 import { translate } from '../../../helpers/l10n';
-import { BranchLike } from '../../../types/branch-like';
 import { Hotspot } from '../../../types/security-hotspots';
 import {
-  Component,
   ExpandDirection,
   FlowLocation,
   LinearIssueLocation,
@@ -35,10 +34,8 @@ import {
 } from '../../../types/types';
 import SnippetViewer from '../../issues/crossComponentSourceViewer/SnippetViewer';
 import HotspotPrimaryLocationBox from './HotspotPrimaryLocationBox';
-import HotspotSnippetHeader from './HotspotSnippetHeader';
 
 export interface HotspotSnippetContainerRendererProps {
-  branchLike?: BranchLike;
   highlightedSymbols: string[];
   hotspot: Hotspot;
   loading: boolean;
@@ -50,7 +47,6 @@ export interface HotspotSnippetContainerRendererProps {
   sourceLines: SourceLine[];
   sourceViewerFile: SourceViewerFile;
   secondaryLocations: FlowLocation[];
-  component: Component;
 }
 
 const noop = () => undefined;
@@ -111,16 +107,14 @@ export default function HotspotSnippetContainerRenderer(
   props: HotspotSnippetContainerRendererProps
 ) {
   const {
-    branchLike,
     highlightedSymbols,
     hotspot,
     loading,
     locations: primaryLocations,
-    sourceLines,
-    sourceViewerFile,
     secondaryLocations,
-    component,
     selectedHotspotLocation,
+    sourceLines,
+    sourceViewerFile,
   } = props;
 
   const scrollableRef = React.useRef<HTMLDivElement>(null);
@@ -153,8 +147,6 @@ export default function HotspotSnippetContainerRenderer(
       )}
 
       <SourceFileWrapper className="sw-box-border sw-w-full sw-rounded-1" ref={scrollableRef}>
-        <HotspotSnippetHeader hotspot={hotspot} component={component} branchLike={branchLike} />
-
         <Spinner className="big-spacer" loading={loading} />
 
         {!loading && sourceLines.length > 0 && (
index ddf494953fc21827db60714b320f24e38b878350..453c2d7ac615e778fb8b1eb844cae8214442322e 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+
 import { withTheme } from '@emotion/react';
 import styled from '@emotion/styled';
 import { ClipboardIconButton, HoverLink, Note, themeBorder, themeColor } from 'design-system';
@@ -50,8 +51,11 @@ function HotspotSnippetHeader(props: HotspotSnippetHeaderProps) {
   const displayProjectName = component.qualifier === ComponentQualifier.Application;
 
   return (
-    <StyledHeader className="sw-flex sw-justify-between sw-gap-2 sw-px-4 sw-py-3 sw-box-border">
-      <Note className="sw-flex sw-items-center sw-gap-2 sw-flex-wrap sw-flex-1  sw-my-1/2">
+    <StyledHeader
+      className={`sw-box-border sw-flex sw-gap-2 sw-justify-between -sw-mb-4 sw-mt-6 sw-px-4
+                  sw-py-3`}
+    >
+      <Note className="sw-flex sw-flex-1 sw-flex-wrap sw-gap-2 sw-items-center sw-my-1/2">
         {displayProjectName && (
           <span>
             <HoverLink to={getBranchLikeUrl(project.key, branchLike)}>
@@ -82,7 +86,7 @@ function HotspotSnippetHeader(props: HotspotSnippetHeaderProps) {
 
 const StyledHeader = withTheme(styled.div`
   background-color: ${themeColor('codeLine')};
-  border-bottom: ${themeBorder('default', 'codeLineBorder')};
+  border: ${themeBorder('default', 'codeLineBorder')};
 `);
 
 export default withCurrentUserContext(HotspotSnippetHeader);
index 2401739e699fb8856903f12d5234ccde10b8d773..1394845f0858f5c5485906d2bcd5123874b29944 100644 (file)
@@ -186,6 +186,7 @@ export default function HotspotViewerTabs(props: Props) {
         branchLike={branchLike}
         component={component}
         hotspot={hotspot}
+        isCodeTab={currentTab.value === TabKeys.Code}
         isCompressed={isCompressed}
         isScrolled={isScrolled}
         onUpdateHotspot={props.onUpdateHotspot}