@@ -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} /> | |||
)} | |||
</> | |||
); | |||
@@ -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} |
@@ -17,16 +17,15 @@ | |||
* 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 && ( |
@@ -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); |
@@ -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} |