mirror of https://github.com/harness/drone.git
feat: [AH-1118]: Support Showing Account/Org Level scan data in registry ui (#3574)
* feat: [AH-1118]: remove duplicate variables * feat: [AH-1118]: update failing test config * feat: [AH-1118]: fix issue with redirecting to tab on click of ssca and sto integration overview cards on version details page * feat: [AH-1118]: Support showing note in configuration page * feat: [AH-118]: Support different project, org in version details page for ssca and sto datamain
parent
642fa7e2a5
commit
7bbd5cdef1
|
@ -90,7 +90,7 @@ module.exports = {
|
|||
// }
|
||||
// },
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(date-fns|lodash-es|@harnessio/uicore|@harnessio/design-system|@harnessio/react-har-service-client|@harnessio/react-ssca-manager-client)/)'
|
||||
'node_modules/(?!(date-fns|lodash-es|@harnessio/uicore|@harnessio/design-system|@harnessio/react-har-service-client|@harnessio/react-ssca-manager-client|@harnessio/react-ng-manager-client)/)'
|
||||
],
|
||||
testPathIgnorePatterns: ['<rootDir>/dist', '<rootDir>/src/static']
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
"@harnessio/design-system": "^2.1.1",
|
||||
"@harnessio/icons": "^2.1.9",
|
||||
"@harnessio/react-har-service-client": "^0.15.0",
|
||||
"@harnessio/react-ng-manager-client": "^1.40.0",
|
||||
"@harnessio/react-ssca-manager-client": "^0.65.0",
|
||||
"@harnessio/uicore": "^4.1.2",
|
||||
"@tanstack/react-query": "4.20.4",
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import { useRef } from 'react'
|
||||
import { HARServiceAPIClient } from '@harnessio/react-har-service-client'
|
||||
import { SSCAManagerAPIClient } from '@harnessio/react-ssca-manager-client'
|
||||
import { NGManagerServiceAPIClient } from '@harnessio/react-ng-manager-client'
|
||||
|
||||
import type { CustomUtils } from '@ar/MFEAppTypes'
|
||||
|
||||
|
@ -62,4 +63,14 @@ export default function useOpenApiClient({ on401, customUtils }: useOpenApiClien
|
|||
}
|
||||
})
|
||||
)
|
||||
|
||||
useRef<NGManagerServiceAPIClient>(
|
||||
new NGManagerServiceAPIClient({
|
||||
responseInterceptor,
|
||||
requestInterceptor,
|
||||
urlInterceptor: (url: string) => {
|
||||
return window.getApiBaseUrl(url)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,3 +34,6 @@ export enum PreferenceScope {
|
|||
USER = 'USER',
|
||||
MACHINE = 'MACHINE' // or workstation. This will act as default PreferenceScope
|
||||
}
|
||||
|
||||
export const DEFAULT_ORG = 'default'
|
||||
export const DEFAULT_PROJECT = 'default_project'
|
||||
|
|
|
@ -51,6 +51,15 @@ jest.mock('react-router-dom', () => ({
|
|||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-ng-manager-client', () => ({
|
||||
useGetOrgScopedProjectQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: { content: { data: {} } }
|
||||
}))
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
|
|
|
@ -60,6 +60,15 @@ jest.mock('react-router-dom', () => ({
|
|||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-ng-manager-client', () => ({
|
||||
useGetOrgScopedProjectQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: { content: { data: {} } }
|
||||
}))
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
|
|
|
@ -48,3 +48,9 @@
|
|||
column-gap: var(--spacing-medium);
|
||||
row-gap: var(--spacing-medium);
|
||||
}
|
||||
|
||||
.helperText {
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: 400;
|
||||
color: var(--gray-900);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
// This is an auto-generated file
|
||||
export declare const cardContainer: string
|
||||
export declare const cardHeading: string
|
||||
export declare const helperText: string
|
||||
export declare const includeExcludeWrapper: string
|
||||
export declare const marginTopLarge: string
|
||||
export declare const scannersContainer: string
|
||||
|
|
|
@ -41,7 +41,6 @@ export default function SelectContainerScannersFormSection(
|
|||
}, [packageType])
|
||||
|
||||
if (!availableScannerOptions.length) return <></>
|
||||
|
||||
return (
|
||||
<SelectScannerFormSection
|
||||
title={getString('repositoryDetails.repositoryForm.securityScan.containerScannerSelect.cardTitle')}
|
||||
|
|
|
@ -16,14 +16,15 @@
|
|||
|
||||
import React from 'react'
|
||||
import { useFormikContext } from 'formik'
|
||||
import { FontVariation } from '@harnessio/design-system'
|
||||
import { Icon } from '@harnessio/icons'
|
||||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
import { Checkbox, CheckboxVariant, Container, Layout, Text } from '@harnessio/uicore'
|
||||
|
||||
import { useLicenseStore } from '@ar/hooks'
|
||||
import { String } from '@ar/frameworks/strings'
|
||||
import { Scanners, type RepositoryPackageType } from '@ar/common/types'
|
||||
import { LICENSE_STATE_VALUES } from '@ar/common/LicenseTypes'
|
||||
import type { VirtualRegistryRequest } from '@ar/pages/repository-details/types'
|
||||
import type { ScannerConfigSpec } from '@ar/pages/repository-details/constants'
|
||||
import useCheckRequiredConfigForScan from '@ar/pages/repository-details/hooks/useCheckRequiredConfigForScan/useCheckRequiredConfigForScan'
|
||||
|
||||
import css from './FormContent.module.scss'
|
||||
|
||||
|
@ -38,11 +39,9 @@ interface SelectScannerFormSectionProps {
|
|||
|
||||
export default function SelectScannerFormSection(props: SelectScannerFormSectionProps) {
|
||||
const { options, title, subTitle, readonly } = props
|
||||
const { SSCA_LICENSE_STATE, STO_LICENSE_STATE } = useLicenseStore()
|
||||
const { setFieldValue, values } = useFormikContext<VirtualRegistryRequest>()
|
||||
|
||||
const hasRequiredLicense =
|
||||
SSCA_LICENSE_STATE === LICENSE_STATE_VALUES.ACTIVE && STO_LICENSE_STATE === LICENSE_STATE_VALUES.ACTIVE
|
||||
const { hasRequiredLicense, hasRequiredProjectConfig, orgIdentifier } = useCheckRequiredConfigForScan()
|
||||
|
||||
const handleUpdateFormikState = (event: React.FormEvent<HTMLInputElement>) => {
|
||||
const isChecked = event.currentTarget.checked
|
||||
|
@ -55,7 +54,7 @@ export default function SelectScannerFormSection(props: SelectScannerFormSection
|
|||
}
|
||||
|
||||
const getCheckboxState = (value: ScannerConfigSpec['value']) => {
|
||||
return value === Scanners.AQUA_TRIVY
|
||||
return value === Scanners.AQUA_TRIVY && hasRequiredProjectConfig
|
||||
// return values.scanners?.some(each => each.name === value) || false
|
||||
}
|
||||
|
||||
|
@ -81,6 +80,17 @@ export default function SelectScannerFormSection(props: SelectScannerFormSection
|
|||
</Checkbox>
|
||||
))}
|
||||
</Container>
|
||||
{!hasRequiredProjectConfig && (
|
||||
<Layout.Horizontal flex={{ alignItems: 'center', justifyContent: 'flex-start' }} spacing="small">
|
||||
<Icon name="main-info" color={Color.PRIMARY_7} />
|
||||
<String
|
||||
useRichText
|
||||
vars={{ orgName: orgIdentifier }}
|
||||
className={css.helperText}
|
||||
stringID="repositoryDetails.repositoryForm.securityScan.containerScannerSelect.scannerNoteForRequiredConfiguration"
|
||||
/>
|
||||
</Layout.Horizontal>
|
||||
)}
|
||||
</Layout.Vertical>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -41,6 +41,15 @@ jest.mock('@harnessio/react-har-service-client', () => ({
|
|||
}))
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-ng-manager-client', () => ({
|
||||
useGetOrgScopedProjectQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: { content: { data: {} } }
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify repository configuration form content', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
|
|
|
@ -28,6 +28,15 @@ import SelectContainerScannersFormSection from '../SelectContainerScannersFormSe
|
|||
|
||||
import '../../../RepositoryFactory'
|
||||
|
||||
jest.mock('@harnessio/react-ng-manager-client', () => ({
|
||||
useGetOrgScopedProjectQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: { content: { data: {} } }
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('verify SelectContainerScannersFormSection', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2024 Harness, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useGetOrgScopedProjectQuery } from '@harnessio/react-ng-manager-client'
|
||||
|
||||
import { useAppStore, useLicenseStore } from '@ar/hooks'
|
||||
import { LICENSE_STATE_VALUES } from '@ar/common/LicenseTypes'
|
||||
import { DEFAULT_ORG, DEFAULT_PROJECT } from '@ar/constants'
|
||||
|
||||
export default function useCheckRequiredConfigForScan(): {
|
||||
hasRequiredLicense: boolean
|
||||
hasRequiredProjectConfig: boolean
|
||||
hasRequiredConfig: boolean
|
||||
orgIdentifier: string
|
||||
} {
|
||||
const { scope } = useAppStore()
|
||||
const { orgIdentifier, projectIdentifier } = scope
|
||||
const { SSCA_LICENSE_STATE, STO_LICENSE_STATE } = useLicenseStore()
|
||||
const hasRequiredLicense =
|
||||
SSCA_LICENSE_STATE === LICENSE_STATE_VALUES.ACTIVE && STO_LICENSE_STATE === LICENSE_STATE_VALUES.ACTIVE
|
||||
|
||||
const { isFetching, error } = useGetOrgScopedProjectQuery(
|
||||
{
|
||||
org: orgIdentifier ?? DEFAULT_ORG,
|
||||
project: projectIdentifier ?? DEFAULT_PROJECT
|
||||
},
|
||||
{
|
||||
enabled: !projectIdentifier
|
||||
}
|
||||
)
|
||||
const hasRequiredProjectConfig = !isFetching && !error
|
||||
|
||||
const hasRequiredConfig = hasRequiredLicense && hasRequiredProjectConfig
|
||||
|
||||
return {
|
||||
hasRequiredLicense,
|
||||
hasRequiredProjectConfig,
|
||||
hasRequiredConfig,
|
||||
orgIdentifier: orgIdentifier ?? DEFAULT_ORG
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ repositoryForm:
|
|||
containerScannerSelect:
|
||||
cardTitle: Built-in Container Scanners
|
||||
cardSubTitle: Container scanners detect vulnerabilities in your container images. Select scanner(s) below to add them in your pipeline.
|
||||
scannerNoteForRequiredConfiguration: To enable scanning for account level or org level registries, please create a project with id set to <b>default_project</b> in your <b>{{orgName}}</b> org.
|
||||
tabs:
|
||||
configuration: Configuration
|
||||
packages: '{{ $.artifactList.pageHeading }}'
|
||||
|
|
|
@ -282,25 +282,25 @@ describe('Verify DockerVersionHeader component render', () => {
|
|||
const overviewTab = container.querySelector('div[data-tab-id=overview]')
|
||||
await userEvent.click(overviewTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/overview?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/artifacts/versions/overview?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
|
||||
const artifactDetailsTab = container.querySelector('div[data-tab-id=artifact_details]')
|
||||
await userEvent.click(artifactDetailsTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/artifact_details?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/artifacts/versions/artifact_details?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
|
||||
const sscaTab = container.querySelector('div[data-tab-id=supply_chain]')
|
||||
await userEvent.click(sscaTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/artifact-sources/67a5dccf6d75916b0c3ea1b5/artifacts/67a5dccf6d75916b0c3ea1b6/supply_chain?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/orgs/default/projects/default_project/artifact-sources/67a5dccf6d75916b0c3ea1b5/artifacts/67a5dccf6d75916b0c3ea1b6/supply_chain?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
|
||||
const stoTab = container.querySelector('div[data-tab-id=security_tests]')
|
||||
await userEvent.click(stoTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/pipelines/HARNESS_ARTIFACT_SCAN_PIPELINE/executions/Tbi7s6nETjmOMKU3Qrnm7A/security_tests?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/orgs/default/projects/default_project/pipelines/HARNESS_ARTIFACT_SCAN_PIPELINE/executions/Tbi7s6nETjmOMKU3Qrnm7A/security_tests?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -323,25 +323,25 @@ describe('Verify DockerVersionHeader component render', () => {
|
|||
const overviewTab = container.querySelector('div[data-tab-id=overview]')
|
||||
await userEvent.click(overviewTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/overview?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/artifacts/versions/overview?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
|
||||
const artifactDetailsTab = container.querySelector('div[data-tab-id=artifact_details]')
|
||||
await userEvent.click(artifactDetailsTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/artifact_details?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/artifacts/versions/artifact_details?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
|
||||
const sscaTab = container.querySelector('div[data-tab-id=supply_chain]')
|
||||
await userEvent.click(sscaTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/supply_chain?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/orgs/default/projects/default_project/supply_chain?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
|
||||
const stoTab = container.querySelector('div[data-tab-id=security_tests]')
|
||||
await userEvent.click(stoTab!)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith(
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/security_tests?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/undefined/artifacts/undefined/versions/undefined/orgs/default/projects/default_project/security_tests?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -145,7 +145,7 @@ describe('Verify docker version overview page', () => {
|
|||
await userEvent.click(sscaCard)
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith(
|
||||
'/registries/1/artifacts/1/versions/1/artifact-sources/67a5dccf6d75916b0c3ea1b5/artifacts/67a5dccf6d75916b0c3ea1b6/supply_chain?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/1/artifacts/1/versions/1/orgs/default/projects/default_project/artifact-sources/67a5dccf6d75916b0c3ea1b5/artifacts/67a5dccf6d75916b0c3ea1b6/supply_chain?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -159,7 +159,7 @@ describe('Verify docker version overview page', () => {
|
|||
await userEvent.click(securityTestsCard)
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith(
|
||||
'/registries/1/artifacts/1/versions/1/pipelines/HARNESS_ARTIFACT_SCAN_PIPELINE/executions/Tbi7s6nETjmOMKU3Qrnm7A/security_tests?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
'/registries/1/artifacts/1/versions/1/orgs/default/projects/default_project/pipelines/HARNESS_ARTIFACT_SCAN_PIPELINE/executions/Tbi7s6nETjmOMKU3Qrnm7A/security_tests?digest=sha256:144cdab68a435424250fe06e9a4f8a5f6b6b8a8a55d257bc6ee77476a6ec520d'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -23,8 +23,9 @@ import { useGetDockerArtifactIntegrationDetailsQuery } from '@harnessio/react-ha
|
|||
|
||||
import { encodeRef } from '@ar/hooks/useGetSpaceRef'
|
||||
import { useStrings } from '@ar/frameworks/strings'
|
||||
import { DEFAULT_ORG, DEFAULT_PROJECT } from '@ar/constants'
|
||||
import type { VersionDetailsPathParams } from '@ar/routes/types'
|
||||
import { useDecodedParams, useGetSpaceRef, useRoutes } from '@ar/hooks'
|
||||
import { useAppStore, useDecodedParams, useGetSpaceRef, useRoutes } from '@ar/hooks'
|
||||
import DeploymentsCard from '@ar/pages/version-details/components/DeploymentsCard/DeploymentsCard'
|
||||
import SecurityTestsCard from '@ar/pages/version-details/components/SecurityTestsCard/SecurityTestsCard'
|
||||
import SupplyChainCard from '@ar/pages/version-details/components/SupplyChainCard/SupplyChainCard'
|
||||
|
@ -40,6 +41,8 @@ interface RedirectToTabOptions {
|
|||
artifactId?: string
|
||||
executionIdentifier?: string
|
||||
pipelineIdentifier?: string
|
||||
orgIdentifier?: string
|
||||
projectIdentifier?: string
|
||||
}
|
||||
|
||||
interface VersionOverviewCardsProps {
|
||||
|
@ -51,6 +54,8 @@ export default function VersionOverviewCards(props: VersionOverviewCardsProps) {
|
|||
const { digest = '', cards = [] } = props
|
||||
const { getString } = useStrings()
|
||||
const routes = useRoutes()
|
||||
const { scope } = useAppStore()
|
||||
const { orgIdentifier, projectIdentifier } = scope
|
||||
const pathParams = useDecodedParams<VersionDetailsPathParams>()
|
||||
const history = useHistory()
|
||||
const spaceRef = useGetSpaceRef()
|
||||
|
@ -112,7 +117,9 @@ export default function VersionOverviewCards(props: VersionOverviewCardsProps) {
|
|||
onClick={() => {
|
||||
handleRedirectToTab(VersionDetailsTab.SUPPLY_CHAIN, {
|
||||
sourceId: responseData.sbomDetails?.artifactSourceId,
|
||||
artifactId: responseData.sbomDetails?.artifactId
|
||||
artifactId: responseData.sbomDetails?.artifactId,
|
||||
orgIdentifier: !orgIdentifier ? DEFAULT_ORG : undefined,
|
||||
projectIdentifier: !projectIdentifier ? DEFAULT_PROJECT : undefined
|
||||
})
|
||||
}}
|
||||
orchestrationId={defaultTo(responseData.sbomDetails?.orchestrationId, '')}
|
||||
|
@ -129,7 +136,9 @@ export default function VersionOverviewCards(props: VersionOverviewCardsProps) {
|
|||
onClick={() => {
|
||||
handleRedirectToTab(VersionDetailsTab.SECURITY_TESTS, {
|
||||
executionIdentifier: responseData?.stoDetails?.executionId,
|
||||
pipelineIdentifier: responseData?.stoDetails?.pipelineId
|
||||
pipelineIdentifier: responseData?.stoDetails?.pipelineId,
|
||||
orgIdentifier: !orgIdentifier ? DEFAULT_ORG : undefined,
|
||||
projectIdentifier: !projectIdentifier ? DEFAULT_PROJECT : undefined
|
||||
})
|
||||
}}
|
||||
totalCount={defaultTo(responseData.stoDetails?.total, 0)}
|
||||
|
|
|
@ -20,7 +20,8 @@ import { Container, Tab, Tabs } from '@harnessio/uicore'
|
|||
|
||||
import { useStrings } from '@ar/frameworks/strings'
|
||||
import { useQueryParams } from '@ar/__mocks__/hooks'
|
||||
import { useDecodedParams, useRoutes } from '@ar/hooks'
|
||||
import { DEFAULT_ORG, DEFAULT_PROJECT } from '@ar/constants'
|
||||
import { useAppStore, useDecodedParams, useRoutes } from '@ar/hooks'
|
||||
import type { RepositoryPackageType } from '@ar/common/types'
|
||||
import type { VersionDetailsPathParams } from '@ar/routes/types'
|
||||
import versionFactory from '@ar/frameworks/Version/VersionFactory'
|
||||
|
@ -30,7 +31,9 @@ import { VersionProviderContext } from '@ar/pages/version-details/context/Versio
|
|||
import {
|
||||
versionDetailsPathParams,
|
||||
versionDetailsTabPathParams,
|
||||
versionDetailsTabWithOrgAndProjectPathParams,
|
||||
versionDetailsTabWithPipelineDetailsPathParams,
|
||||
versionDetailsTabWithProjectPathParams,
|
||||
versionDetailsTabWithSSCADetailsPathParams
|
||||
} from '@ar/routes/RouteDestinations'
|
||||
|
||||
|
@ -42,12 +45,14 @@ export default function VersionDetailsTabs(): JSX.Element {
|
|||
const [tab, setTab] = useState('')
|
||||
|
||||
const routes = useRoutes()
|
||||
const { scope } = useAppStore()
|
||||
const history = useHistory()
|
||||
const { getString } = useStrings()
|
||||
const routeDefinitions = useRoutes(true)
|
||||
const { data } = useContext(VersionProviderContext)
|
||||
const pathParams = useDecodedParams<VersionDetailsPathParams>()
|
||||
const { digest } = useQueryParams<DockerVersionDetailsQueryParams>()
|
||||
const { orgIdentifier, projectIdentifier } = scope
|
||||
|
||||
const tabList = useMemo(() => {
|
||||
const versionType = versionFactory?.getVersionType(data?.packageType)
|
||||
|
@ -65,7 +70,9 @@ export default function VersionDetailsTabs(): JSX.Element {
|
|||
...pathParams,
|
||||
versionTab: nextTab,
|
||||
sourceId: data?.sscaArtifactSourceId,
|
||||
artifactId: data?.sscaArtifactId
|
||||
artifactId: data?.sscaArtifactId,
|
||||
orgIdentifier: !orgIdentifier ? DEFAULT_ORG : undefined,
|
||||
projectIdentifier: !projectIdentifier ? DEFAULT_PROJECT : undefined
|
||||
})
|
||||
break
|
||||
case VersionDetailsTab.SECURITY_TESTS:
|
||||
|
@ -73,11 +80,18 @@ export default function VersionDetailsTabs(): JSX.Element {
|
|||
...pathParams,
|
||||
versionTab: nextTab,
|
||||
executionIdentifier: data?.stoExecutionId,
|
||||
pipelineIdentifier: data?.stoPipelineId
|
||||
pipelineIdentifier: data?.stoPipelineId,
|
||||
orgIdentifier: !orgIdentifier ? DEFAULT_ORG : undefined,
|
||||
projectIdentifier: !projectIdentifier ? DEFAULT_PROJECT : undefined
|
||||
})
|
||||
break
|
||||
default:
|
||||
newRoute = routes.toARVersionDetailsTab({ ...pathParams, versionTab: nextTab })
|
||||
newRoute = routes.toARVersionDetailsTab({
|
||||
versionIdentifier: pathParams.versionIdentifier,
|
||||
artifactIdentifier: pathParams.artifactIdentifier,
|
||||
repositoryIdentifier: pathParams.repositoryIdentifier,
|
||||
versionTab: nextTab
|
||||
})
|
||||
break
|
||||
}
|
||||
if (digest) {
|
||||
|
@ -106,8 +120,34 @@ export default function VersionDetailsTabs(): JSX.Element {
|
|||
exact
|
||||
path={[
|
||||
routeDefinitions.toARVersionDetailsTab({ ...versionDetailsTabPathParams }),
|
||||
// with project and org data
|
||||
routeDefinitions.toARVersionDetailsTab({
|
||||
...versionDetailsTabWithOrgAndProjectPathParams
|
||||
}),
|
||||
// ssca with pipeline data
|
||||
routeDefinitions.toARVersionDetailsTab({ ...versionDetailsTabWithSSCADetailsPathParams }),
|
||||
routeDefinitions.toARVersionDetailsTab({ ...versionDetailsTabWithPipelineDetailsPathParams })
|
||||
// ssca with project and pipeline data
|
||||
routeDefinitions.toARVersionDetailsTab({
|
||||
...versionDetailsTabWithSSCADetailsPathParams,
|
||||
...versionDetailsTabWithProjectPathParams
|
||||
}),
|
||||
// ssca with org, project and pipeline data
|
||||
routeDefinitions.toARVersionDetailsTab({
|
||||
...versionDetailsTabWithSSCADetailsPathParams,
|
||||
...versionDetailsTabWithOrgAndProjectPathParams
|
||||
}),
|
||||
// sto with pipeline data
|
||||
routeDefinitions.toARVersionDetailsTab({ ...versionDetailsTabWithPipelineDetailsPathParams }),
|
||||
// sto with project and pipeline data
|
||||
routeDefinitions.toARVersionDetailsTab({
|
||||
...versionDetailsTabWithPipelineDetailsPathParams,
|
||||
...versionDetailsTabWithProjectPathParams
|
||||
}),
|
||||
// sto with org, project and pipeline data
|
||||
routeDefinitions.toARVersionDetailsTab({
|
||||
...versionDetailsTabWithPipelineDetailsPathParams,
|
||||
...versionDetailsTabWithOrgAndProjectPathParams
|
||||
})
|
||||
]}>
|
||||
<VersionDetailsTabWidget
|
||||
onInit={setTab}
|
||||
|
|
|
@ -63,13 +63,17 @@ export const routeDefinitions: ARRouteDefinitionsReturn = {
|
|||
toARVersionDetails: params =>
|
||||
`/registries/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}`,
|
||||
toARVersionDetailsTab: params => {
|
||||
let route = `/registries/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}`
|
||||
if (params.orgIdentifier) route += `/orgs/${params.orgIdentifier}`
|
||||
if (params.projectIdentifier) route += `/projects/${params.projectIdentifier}`
|
||||
if (params.sourceId && params.artifactId) {
|
||||
return `/registries/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}/artifact-sources/${params.sourceId}/artifacts/${params.artifactId}/${params.versionTab}`
|
||||
route += `/artifact-sources/${params.sourceId}/artifacts/${params.artifactId}`
|
||||
}
|
||||
if (params.pipelineIdentifier && params.executionIdentifier) {
|
||||
return `/registries/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}/pipelines/${params.pipelineIdentifier}/executions/${params.executionIdentifier}/${params.versionTab}`
|
||||
route += `/pipelines/${params.pipelineIdentifier}/executions/${params.executionIdentifier}`
|
||||
}
|
||||
return `/registries/${params?.repositoryIdentifier}/artifacts/${params?.artifactIdentifier}/versions/${params?.versionIdentifier}/${params.versionTab}`
|
||||
route += `/${params.versionTab}`
|
||||
return route
|
||||
},
|
||||
toARRepositoryWebhookDetails: params =>
|
||||
`/registries/${params?.repositoryIdentifier}/webhooks/${params?.webhookIdentifier}`,
|
||||
|
|
|
@ -66,6 +66,17 @@ export const versionDetailsTabPathParams: VersionDetailsTabPathParams = {
|
|||
versionTab: ':versionTab'
|
||||
}
|
||||
|
||||
export const versionDetailsTabWithProjectPathParams: VersionDetailsTabPathParams = {
|
||||
...versionDetailsTabPathParams,
|
||||
projectIdentifier: ':projectIdentifier'
|
||||
}
|
||||
|
||||
export const versionDetailsTabWithOrgAndProjectPathParams: VersionDetailsTabPathParams = {
|
||||
...versionDetailsTabPathParams,
|
||||
orgIdentifier: ':orgIdentifier',
|
||||
projectIdentifier: ':projectIdentifier'
|
||||
}
|
||||
|
||||
export const versionDetailsTabWithPipelineDetailsPathParams: VersionDetailsTabPathParams = {
|
||||
...versionDetailsTabPathParams,
|
||||
pipelineIdentifier: ':pipelineIdentifier',
|
||||
|
|
|
@ -41,6 +41,8 @@ export interface VersionDetailsTabPathParams extends VersionDetailsPathParams {
|
|||
executionIdentifier?: string
|
||||
artifactId?: string
|
||||
sourceId?: string
|
||||
orgIdentifier?: string
|
||||
projectIdentifier?: string
|
||||
}
|
||||
|
||||
export interface RedirectPageQueryParams {
|
||||
|
|
|
@ -87,6 +87,7 @@ export interface StringsMap {
|
|||
'repositoryDetails.repositoryForm.repositoryUpdated': string
|
||||
'repositoryDetails.repositoryForm.securityScan.containerScannerSelect.cardSubTitle': string
|
||||
'repositoryDetails.repositoryForm.securityScan.containerScannerSelect.cardTitle': string
|
||||
'repositoryDetails.repositoryForm.securityScan.containerScannerSelect.scannerNoteForRequiredConfiguration': string
|
||||
'repositoryDetails.repositoryForm.securityScan.title': string
|
||||
'repositoryDetails.repositoryForm.selectRepoType': string
|
||||
'repositoryDetails.repositoryForm.title': string
|
||||
|
|
|
@ -1952,6 +1952,11 @@
|
|||
dependencies:
|
||||
"@harnessio/oats-cli" "^3.0.0"
|
||||
|
||||
"@harnessio/react-ng-manager-client@^1.40.0":
|
||||
version "1.40.0"
|
||||
resolved "https://registry.yarnpkg.com/@harnessio/react-ng-manager-client/-/react-ng-manager-client-1.40.0.tgz#e874e9afe1b2358d85364d5e23aabe9f6157bae8"
|
||||
integrity sha512-PETKrA+4TmFs3e+Ok99zPi0ngvGwVJqX5HKczxTWtaDrfXiu/ktZYX5pDN9GBBibShadT0ONbRe4xN6ILFPIuA==
|
||||
|
||||
"@harnessio/react-ssca-manager-client@^0.65.0":
|
||||
version "0.65.0"
|
||||
resolved "https://registry.yarnpkg.com/@harnessio/react-ssca-manager-client/-/react-ssca-manager-client-0.65.0.tgz#8088869e282c5268bf1fefb9715652e0fc1a8940"
|
||||
|
|
Loading…
Reference in New Issue