mirror of
https://github.com/harness/drone.git
synced 2025-05-01 21:21:11 +00:00
Add shield icon and live issue count to tab
This commit is contained in:
parent
a55f41a63e
commit
72c0b92729
@ -14,35 +14,35 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ChildAppMounter from 'framework/microfrontends/ChildAppMounter'
|
import type { STOAppCustomProps } from '@harness/microfrontends'
|
||||||
import React, { lazy, useCallback, useMemo, useRef, useState } from 'react'
|
|
||||||
import { Container, Layout, PageBody, PageSpinner, Tabs, Text } from '@harnessio/uicore'
|
|
||||||
import { FontVariation } from '@harnessio/design-system'
|
import { FontVariation } from '@harnessio/design-system'
|
||||||
import type { ParentContext, STOAppCustomProps } from '@harness/microfrontends'
|
import { Container, Layout, PageBody, PageSpinner, Tabs, Text } from '@harnessio/uicore'
|
||||||
|
import { useAppContext } from 'AppContext'
|
||||||
|
import { ExecutionState, ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus'
|
||||||
|
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
||||||
|
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
|
||||||
|
import { tabContainerCSS, TabTitleWithCount } from 'components/TabTitleWithCount/TabTitleWithCount'
|
||||||
|
import ChildAppMounter from 'framework/microfrontends/ChildAppMounter'
|
||||||
|
import { useStrings } from 'framework/strings'
|
||||||
|
import { useScrollTop } from 'hooks/useScrollTop'
|
||||||
|
import { useSetPageContainerWidthVar } from 'hooks/useSetPageContainerWidthVar'
|
||||||
|
import { compact } from 'lodash-es'
|
||||||
|
import React, { lazy, useCallback, useMemo, useRef, useState } from 'react'
|
||||||
import { Render } from 'react-jsx-match'
|
import { Render } from 'react-jsx-match'
|
||||||
import { useHistory, useParams } from 'react-router-dom'
|
import { useHistory, useParams } from 'react-router-dom'
|
||||||
import { compact } from 'lodash-es'
|
import type { TypesPullReq, TypesRepository } from 'services/code'
|
||||||
import { useAppContext } from 'AppContext'
|
import { useFrontendExecutionForRepo, useFrontendExecutionIssueCounts } from 'services/sto/stoComponents'
|
||||||
import { useStrings } from 'framework/strings'
|
import { CodeIcon } from 'utils/GitUtils'
|
||||||
import { RepositoryPageHeader } from 'components/RepositoryPageHeader/RepositoryPageHeader'
|
|
||||||
import { useFrontendExecutionForRepo } from 'services/sto/stoComponents'
|
|
||||||
import type { Identifier } from 'utils/types'
|
import type { Identifier } from 'utils/types'
|
||||||
import { getErrorMessage, PullRequestSection } from 'utils/Utils'
|
import { getErrorMessage, PullRequestSection } from 'utils/Utils'
|
||||||
import { CodeIcon } from 'utils/GitUtils'
|
|
||||||
import type { TypesPullReq, TypesRepository } from 'services/code'
|
|
||||||
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
|
||||||
import { TabTitleWithCount, tabContainerCSS } from 'components/TabTitleWithCount/TabTitleWithCount'
|
|
||||||
import { ExecutionStatus } from 'components/ExecutionStatus/ExecutionStatus'
|
|
||||||
import { useSetPageContainerWidthVar } from 'hooks/useSetPageContainerWidthVar'
|
|
||||||
import { useScrollTop } from 'hooks/useScrollTop'
|
|
||||||
import { PullRequestMetaLine } from './PullRequestMetaLine'
|
|
||||||
import { Conversation } from './Conversation/Conversation'
|
|
||||||
import { Checks } from './Checks/Checks'
|
|
||||||
import { Changes } from '../../components/Changes/Changes'
|
import { Changes } from '../../components/Changes/Changes'
|
||||||
|
import { Checks } from './Checks/Checks'
|
||||||
|
import { Conversation } from './Conversation/Conversation'
|
||||||
|
import css from './PullRequest.module.scss'
|
||||||
import { PullRequestCommits } from './PullRequestCommits/PullRequestCommits'
|
import { PullRequestCommits } from './PullRequestCommits/PullRequestCommits'
|
||||||
|
import { PullRequestMetaLine } from './PullRequestMetaLine'
|
||||||
import { PullRequestTitle } from './PullRequestTitle'
|
import { PullRequestTitle } from './PullRequestTitle'
|
||||||
import { useGetPullRequestInfo } from './useGetPullRequestInfo'
|
import { useGetPullRequestInfo } from './useGetPullRequestInfo'
|
||||||
import css from './PullRequest.module.scss'
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const RemoteSTOApp = lazy(() => import(`stoV2/App`))
|
const RemoteSTOApp = lazy(() => import(`stoV2/App`))
|
||||||
@ -51,6 +51,7 @@ const RemotePipelineSecurityView = lazy(() => import(`stoV2/PipelineSecurityView
|
|||||||
|
|
||||||
export default function PullRequest() {
|
export default function PullRequest() {
|
||||||
const history = useHistory()
|
const history = useHistory()
|
||||||
|
const { accountId, orgIdentifier = '', projectIdentifier = '' } = useParams<Identifier>()
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
const { routes, standalone, routingId } = useAppContext()
|
const { routes, standalone, routingId } = useAppContext()
|
||||||
const { parentContextObj } = useAppContext()
|
const { parentContextObj } = useAppContext()
|
||||||
@ -72,6 +73,35 @@ export default function PullRequest() {
|
|||||||
retryOnErrorFunc
|
retryOnErrorFunc
|
||||||
} = useGetPullRequestInfo()
|
} = useGetPullRequestInfo()
|
||||||
|
|
||||||
|
const gitUrl = repoMetadata?.git_url
|
||||||
|
const prNumber = pullReqMetadata?.number
|
||||||
|
const { data } = useFrontendExecutionForRepo(
|
||||||
|
{
|
||||||
|
queryParams: {
|
||||||
|
accountId,
|
||||||
|
orgId: orgIdentifier,
|
||||||
|
projectId: projectIdentifier,
|
||||||
|
gitUrl: gitUrl || '',
|
||||||
|
prNumber,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ enabled: gitUrl !== undefined && prNumber !== undefined }
|
||||||
|
)
|
||||||
|
|
||||||
|
const { data: countData } = useFrontendExecutionIssueCounts(
|
||||||
|
{
|
||||||
|
queryParams: {
|
||||||
|
accountId,
|
||||||
|
orgId: orgIdentifier,
|
||||||
|
projectId: projectIdentifier,
|
||||||
|
executionIds: data?.executionId || ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ enabled: data?.executionId !== undefined }
|
||||||
|
)
|
||||||
|
const counts = countData && data?.executionId !== undefined && countData[data?.executionId] ? countData[data?.executionId] : undefined
|
||||||
|
const issueCount = counts ? (counts.newCritical || 0) + (counts.newHigh || 0) + (counts.newMedium || 0) + (counts.newLow || 0) : undefined
|
||||||
|
|
||||||
const onAddDescriptionClick = useCallback(() => {
|
const onAddDescriptionClick = useCallback(() => {
|
||||||
setShowEditDescription(true)
|
setShowEditDescription(true)
|
||||||
history.replace(
|
history.replace(
|
||||||
@ -268,36 +298,45 @@ export default function PullRequest() {
|
|||||||
id: PullRequestSection.SECURITY_ISSUES,
|
id: PullRequestSection.SECURITY_ISSUES,
|
||||||
title: (
|
title: (
|
||||||
<TabTitleWithCount
|
<TabTitleWithCount
|
||||||
icon="security-stage"
|
icon="shield-gears"
|
||||||
iconSize={14}
|
iconSize={14}
|
||||||
title="New Security Issues"
|
title="New Security Issues"
|
||||||
countElement={
|
countElement={
|
||||||
pullReqChecksDecision?.overallStatus ? (
|
pullReqChecksDecision?.overallStatus ? (
|
||||||
<Container className={css.checksCount}>
|
<Container className={css.checksCount}>
|
||||||
<Layout.Horizontal className={css.checksCountLayout}>
|
<Layout.Horizontal className={css.checksCountLayout}>
|
||||||
<ExecutionStatus
|
{(pullReqChecksDecision?.overallStatus === ExecutionState.RUNNING
|
||||||
status={pullReqChecksDecision?.overallStatus}
|
|| pullReqChecksDecision?.overallStatus === ExecutionState.ERROR)
|
||||||
noBackground
|
&& (
|
||||||
iconOnly
|
<ExecutionStatus
|
||||||
iconSize={15}
|
status={pullReqChecksDecision?.overallStatus}
|
||||||
/>
|
noBackground
|
||||||
|
iconOnly
|
||||||
<Text
|
iconSize={20}
|
||||||
color={pullReqChecksDecision?.color}
|
/>
|
||||||
padding={{ left: 'xsmall' }}
|
)}
|
||||||
tag="span"
|
|
||||||
font={{ variation: FontVariation.FORM_MESSAGE_WARNING }}>
|
|
||||||
{pullReqChecksDecision?.count[pullReqChecksDecision?.overallStatus]}
|
|
||||||
</Text>
|
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</Container>
|
</Container>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
count={undefined}
|
count={pullReqChecksDecision?.overallStatus !== ExecutionState.RUNNING ? issueCount : undefined}
|
||||||
padding={{ left: 'medium' }}
|
padding={{ left: 'medium' }}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
panel: <PullRequestSecurityView parentContextObj={parentContextObj} gitUrl={repoMetadata?.git_url} prNumber={pullReqMetadata?.number} />
|
panel: data?.executionId ? (
|
||||||
|
<Container width="100%" height="100%">
|
||||||
|
<ChildAppMounter<STOAppCustomProps>
|
||||||
|
ChildApp={RemoteSTOApp}
|
||||||
|
customComponents={{ /*UserLabel, UsefulOrNot*/ }}
|
||||||
|
customHooks={{ /*useGetSettingValue, useGetPipelineSummary*/ }}
|
||||||
|
parentContextObj={parentContextObj}
|
||||||
|
>
|
||||||
|
<RemotePipelineSecurityView pipelineExecutionDetail={{ pipelineExecutionSummary: { planExecutionId: data?.executionId } }} isPullRequest={true} />
|
||||||
|
</ChildAppMounter>
|
||||||
|
</Container>
|
||||||
|
) : (
|
||||||
|
<PageSpinner />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
@ -309,38 +348,6 @@ export default function PullRequest() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PullRequestSecurityView: React.FC<{ parentContextObj: ParentContext, gitUrl?: string, prNumber?: number }> = ({ parentContextObj, gitUrl, prNumber }) => {
|
|
||||||
const { accountId, orgIdentifier = '', projectIdentifier = '' } = useParams<Identifier>()
|
|
||||||
|
|
||||||
const { data } = useFrontendExecutionForRepo(
|
|
||||||
{
|
|
||||||
queryParams: {
|
|
||||||
accountId,
|
|
||||||
orgId: orgIdentifier,
|
|
||||||
projectId: projectIdentifier,
|
|
||||||
gitUrl: gitUrl || '',
|
|
||||||
prNumber,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ enabled: gitUrl !== undefined }
|
|
||||||
)
|
|
||||||
|
|
||||||
return data?.executionId ? (
|
|
||||||
<Container width="100%" height="100%">
|
|
||||||
<ChildAppMounter<STOAppCustomProps>
|
|
||||||
ChildApp={RemoteSTOApp}
|
|
||||||
customComponents={{ /*UserLabel, UsefulOrNot*/ }}
|
|
||||||
customHooks={{ /*useGetSettingValue, useGetPipelineSummary*/ }}
|
|
||||||
parentContextObj={parentContextObj}
|
|
||||||
>
|
|
||||||
<RemotePipelineSecurityView pipelineExecutionDetail={{ pipelineExecutionSummary: { planExecutionId: data?.executionId } }} isPullRequest={true} />
|
|
||||||
</ChildAppMounter>
|
|
||||||
</Container>
|
|
||||||
) : (
|
|
||||||
<PageSpinner />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - Move pullReqChecksDecision to individual component to avoid weird
|
// - Move pullReqChecksDecision to individual component to avoid weird
|
||||||
// re-rendering everything in this page during its polling. Use an atom?
|
// re-rendering everything in this page during its polling. Use an atom?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user