feat: [AH-621] Support deployments table for generic artifact version (#3196)

* feat: [AH-621]: fix PR comments
* feat: [AH-621]: fix PR comments
* feat: [AH-621] Support deployments table for generic artifact version
BT-10437
Shivanand Sonnad 2024-12-24 10:40:12 +00:00 committed by Harness
parent b9de5c7217
commit d0d3ab1057
19 changed files with 183 additions and 120 deletions

View File

@ -27,7 +27,7 @@ export const LegendList = ({ items }: { items: PieChartItem[] }) => {
<Layout.Vertical>
{items.map(item => {
return (
<Layout.Horizontal spacing={'xsmall'} key={item.value}>
<Layout.Horizontal spacing={'xsmall'} key={item.label}>
<DonutChartTag
color={item.color}
backgroundColor={item.backgroundColor}>{`${item.label} ${item.value}`}</DonutChartTag>

View File

@ -0,0 +1,58 @@
/*
* 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 React from 'react'
import { defaultTo } from 'lodash-es'
import { Card, Layout, Text } from '@harnessio/uicore'
import { Color, FontVariation } from '@harnessio/design-system'
import { useGetDockerArtifactManifestsQuery } from '@harnessio/react-har-service-client'
import { useStrings } from '@ar/frameworks/strings'
import { encodeRef } from '@ar/hooks/useGetSpaceRef'
import { useDecodedParams, useGetSpaceRef } from '@ar/hooks'
import type { VersionDetailsPathParams } from '@ar/routes/types'
import css from '../DockerVersion.module.scss'
export default function DockerDeploymentsCard() {
const { getString } = useStrings()
const registryRef = useGetSpaceRef()
const params = useDecodedParams<VersionDetailsPathParams>()
const { data: manifestsData } = useGetDockerArtifactManifestsQuery({
registry_ref: registryRef,
artifact: encodeRef(params.artifactIdentifier),
version: params.versionIdentifier
})
return (
<Card className={css.containerDetailsCard}>
<Layout.Vertical spacing="large">
<Text font={{ variation: FontVariation.CARD_TITLE }}>{getString('versionDetails.cards.container.title')}</Text>
<Layout.Vertical spacing="small">
<Text lineClamp={1} font={{ variation: FontVariation.BODY }}>
{defaultTo(params.artifactIdentifier, getString('na'))}
</Text>
<Text lineClamp={1} color={Color.GREY_500} font={{ variation: FontVariation.SMALL }}>
{getString('versionDetails.cards.container.versionDigest', {
version: defaultTo(params.versionIdentifier, getString('na')),
digest: defaultTo(manifestsData?.content.data.manifests?.length, 0)
})}
</Text>
</Layout.Vertical>
</Layout.Vertical>
</Card>
)
}

View File

@ -0,0 +1,23 @@
/*
* 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 React from 'react'
import DeploymentsContent from '@ar/pages/version-details/components/DeploymentsContent/DeploymentsContent'
import DockerDeploymentsCard from './DockerDeploymentsCards'
export default function DockerDeploymentsContent() {
return <DeploymentsContent prefixCard={<DockerDeploymentsCard />} />
}

View File

@ -62,16 +62,8 @@
margin: 0px;
}
.deploymentTablePageBody {
--page-header-height: 350px;
}
.subHeaderItems {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--spacing-medium);
width: 100%;
.containerDetailsCard {
min-width: 250px;
}
.setupClientBtn {

View File

@ -18,10 +18,9 @@
// This is an auto-generated file
export declare const card: string
export declare const cardContainer: string
export declare const deploymentTablePageBody: string
export declare const containerDetailsCard: string
export declare const gridContainer: string
export declare const manifestContainer: string
export declare const margin0: string
export declare const pageBody: string
export declare const setupClientBtn: string
export declare const subHeaderItems: string

View File

@ -34,7 +34,7 @@ import DockerArtifactDetailsContent from './DockerArtifactDetailsContent'
import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants'
import DockerArtifactSecurityTestsContent from './DockerArtifactSecurityTestsContent'
import DockerVersionOSSContent from './DockerVersionOSSContent/DockerVersionOSSContent'
import DockerDeploymentsContent from './DockerDeploymentsContent'
import DockerDeploymentsContent from './DockerDeploymentsContent/DockerDeploymentsContent'
export class DockerVersionType extends VersionStep<ArtifactVersionSummary> {
protected packageType = RepositoryPackageType.DOCKER

View File

@ -1,70 +0,0 @@
/*
* 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 React from 'react'
import { defaultTo } from 'lodash-es'
import { Card, Layout, Text } from '@harnessio/uicore'
import { Color, FontVariation } from '@harnessio/design-system'
import type { DeploymentStats, DockerManifestDetails } from '@harnessio/react-har-service-client'
import type { LayoutProps } from '@harnessio/uicore/dist/layouts/Layout'
import { useStrings } from '@ar/frameworks/strings'
import DeploymentsCard from '@ar/pages/version-details/components/DeploymentsCard/DeploymentsCard'
import css from './DeploymentOverviewCards.module.scss'
interface artifactDetails {
artifactName: string
version: string
digests: DockerManifestDetails[]
}
interface DeploymentOverviewCardsProps extends LayoutProps {
artifactDetails?: artifactDetails
deploymentStats?: DeploymentStats
}
export default function DeploymentOverviewCards(props: DeploymentOverviewCardsProps) {
const { artifactDetails, deploymentStats, ...rest } = props
const { getString } = useStrings()
return (
<Layout.Horizontal width="100%" spacing="medium" {...rest}>
<Card className={css.containerDetailsCard}>
<Layout.Vertical spacing="large">
<Text font={{ variation: FontVariation.CARD_TITLE }}>
{getString('versionDetails.cards.container.title')}
</Text>
<Layout.Vertical spacing="small">
<Text font={{ variation: FontVariation.BODY }}>
{defaultTo(artifactDetails?.artifactName, getString('na'))}
</Text>
<Text color={Color.GREY_500} font={{ variation: FontVariation.SMALL }}>
{getString('versionDetails.cards.container.versionDigest', {
version: defaultTo(artifactDetails?.version, getString('na')),
digest: defaultTo(artifactDetails?.digests?.length, 0)
})}
</Text>
</Layout.Vertical>
</Layout.Vertical>
</Card>
<DeploymentsCard
prodCount={defaultTo(deploymentStats?.Production, 0)}
nonProdCount={defaultTo(deploymentStats?.PreProduction, 0)}
hideBuildDetails
/>
</Layout.Horizontal>
)
}

View File

@ -26,6 +26,7 @@ import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants'
import GenericVersionHeader from './GenericVersionHeader'
import GenericOverviewPage from './pages/overview/OverviewPage'
import GenericArtifactDetailsPage from './pages/artifact-details/GenericArtifactDetailsPage'
import GenericArtifactDeploymentsPage from './pages/deployments/GenericArtifactDeploymentsPage'
export class GenericVersionType extends VersionStep<ArtifactVersionSummary> {
protected packageType = RepositoryPackageType.GENERIC
@ -51,7 +52,7 @@ export class GenericVersionType extends VersionStep<ArtifactVersionSummary> {
case VersionDetailsTab.ARTIFACT_DETAILS:
return <GenericArtifactDetailsPage />
case VersionDetailsTab.DEPLOYMENTS:
return <></>
return <GenericArtifactDeploymentsPage />
case VersionDetailsTab.OSS:
return <></>
default:

View File

@ -0,0 +1,22 @@
/*
* 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 React from 'react'
import DeploymentsContent from '@ar/pages/version-details/components/DeploymentsContent/DeploymentsContent'
export default function GenericArtifactDeploymentsPage() {
return <DeploymentsContent />
}

View File

@ -0,0 +1,42 @@
/*
* 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 React from 'react'
import { defaultTo } from 'lodash-es'
import { Layout } from '@harnessio/uicore'
import type { DeploymentStats } from '@harnessio/react-har-service-client'
import type { LayoutProps } from '@harnessio/uicore/dist/layouts/Layout'
import DeploymentsCard from '@ar/pages/version-details/components/DeploymentsCard/DeploymentsCard'
interface DeploymentOverviewCardsProps extends LayoutProps {
prefixCards?: React.ReactNode
deploymentStats?: DeploymentStats
}
export default function DeploymentOverviewCards(props: DeploymentOverviewCardsProps) {
const { deploymentStats, prefixCards, ...rest } = props
return (
<Layout.Horizontal width="100%" spacing="medium" {...rest}>
{prefixCards}
<DeploymentsCard
prodCount={defaultTo(deploymentStats?.Production, 0)}
nonProdCount={defaultTo(deploymentStats?.PreProduction, 0)}
hideBuildDetails
/>
</Layout.Horizontal>
)
}

View File

@ -14,6 +14,14 @@
* limitations under the License.
*/
.containerDetailsCard {
min-width: 250px;
.subHeaderItems {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--spacing-medium);
width: 100%;
}
.deploymentTablePageBody {
--page-header-height: 350px;
}

View File

@ -16,4 +16,5 @@
/* eslint-disable */
// This is an auto-generated file
export declare const containerDetailsCard: string
export declare const deploymentTablePageBody: string
export declare const subHeaderItems: string

View File

@ -16,9 +16,8 @@
import React, { useMemo, useRef } from 'react'
import { Expander } from '@blueprintjs/core'
import { defaultTo } from 'lodash-es'
import { flushSync } from 'react-dom'
import { useGetArtifactDeploymentsQuery, useGetDockerArtifactManifestsQuery } from '@harnessio/react-har-service-client'
import { useGetArtifactDeploymentsQuery } from '@harnessio/react-har-service-client'
import {
Button,
ButtonVariation,
@ -34,17 +33,21 @@ import { useStrings } from '@ar/frameworks/strings'
import { encodeRef } from '@ar/hooks/useGetSpaceRef'
import type { VersionDetailsPathParams } from '@ar/routes/types'
import EnvironmentTypeSelector from '@ar/components/EnvironmentTypeSelector/EnvironmentTypeSelector'
import DockerVersionDeploymentsTable from '@ar/pages/version-details/components/DeploymentsTable/DeploymentsTable'
import DeploymentOverviewCards from './components/DeploymentOverviewCards/DeploymentOverviewCards'
import DeploymentsTable from './DeploymentsTable/DeploymentsTable'
import DeploymentOverviewCards from './DeploymentOverviewCards/DeploymentOverviewCards'
import {
useArtifactVersionDeploymentsTableQueryParamOptions,
type ArtifactVersionDeploymentsTableQueryParams
} from '../components/DeploymentsTable/utils'
ArtifactVersionDeploymentsTableQueryParams,
useArtifactVersionDeploymentsTableQueryParamOptions
} from './utils'
import css from './DockerVersion.module.scss'
import css from './DeploymentsContent.module.scss'
export default function DockerDeploymentsContent() {
interface DeploymentsContentProps {
prefixCard?: React.ReactNode
}
export default function DeploymentsContent(props: DeploymentsContentProps) {
const { useQueryParams, useUpdateQueryParams, usePreferenceStore } = useParentHooks()
const { updateQueryParams } = useUpdateQueryParams<Partial<ArtifactVersionDeploymentsTableQueryParams>>()
const queryParamOptions = useArtifactVersionDeploymentsTableQueryParamOptions()
@ -74,12 +77,6 @@ export default function DockerDeploymentsContent() {
}
})
const { data: manifestsData } = useGetDockerArtifactManifestsQuery({
registry_ref: registryRef,
artifact: encodeRef(params.artifactIdentifier),
version: params.versionIdentifier
})
const handleClearFilters = (): void => {
flushSync(searchRef.current.clear)
updateQueryParams({
@ -94,16 +91,7 @@ export default function DockerDeploymentsContent() {
return (
<Layout.Vertical padding="large" spacing="medium">
{responseData && (
<DeploymentOverviewCards
artifactDetails={{
artifactName: params.artifactIdentifier,
version: params.versionIdentifier,
digests: defaultTo(manifestsData?.content.data.manifests, [])
}}
deploymentStats={responseData?.deploymentsStats}
/>
)}
<DeploymentOverviewCards prefixCards={props.prefixCard} deploymentStats={responseData?.deploymentsStats} />
<div className={css.subHeaderItems}>
<EnvironmentTypeSelector
value={environmentTypes}
@ -131,7 +119,6 @@ export default function DockerDeploymentsContent() {
noData={{
when: () => !responseData?.deployments.itemCount,
icon: 'thinner-code-repos',
// image: getEmptyStateIllustration(hasFilter, module),
messageTitle: hasFilter
? getString('noResultsFound')
: getString('versionDetails.deploymentsTable.noDeploymentsTitle'),
@ -142,7 +129,7 @@ export default function DockerDeploymentsContent() {
)
}}>
{responseData && (
<DockerVersionDeploymentsTable
<DeploymentsTable
data={responseData}
gotoPage={pageNumber => updateQueryParams({ page: pageNumber })}
onPageSizeChange={newSize => updateQueryParams({ size: newSize, page: DEFAULT_PAGE_INDEX })}

View File

@ -24,7 +24,6 @@ import type { ArtifactDeploymentsDetail, ArtifactDeploymentsDetails } from '@har
import { useParentHooks } from '@ar/hooks'
import { useStrings } from '@ar/frameworks/strings'
import type { DockerVersionDeploymentsListSortBy } from './types'
import {
DeploymentPipelineCell,
EnvironmentNameCell,
@ -34,10 +33,11 @@ import {
LastModifiedCell,
ServiceListCell
} from './DeploymentsTableCells'
import type { DeploymentsListSortBy } from '../types'
import css from './DeploymentsTable.module.scss'
interface DockerVersionDeploymentsTableProps {
interface DeploymentsTableProps {
data: ArtifactDeploymentsDetails
gotoPage: (pageNumber: number) => void
onPageSizeChange?: PaginationProps['onPageSizeChange']
@ -45,7 +45,7 @@ interface DockerVersionDeploymentsTableProps {
sortBy: string[]
}
export default function DockerVersionDeploymentsTable(props: DockerVersionDeploymentsTableProps) {
export default function DeploymentsTable(props: DeploymentsTableProps) {
const { data, gotoPage, onPageSizeChange, setSortBy, sortBy } = props
const { useDefaultPaginationProps } = useParentHooks()
const { getString } = useStrings()
@ -67,7 +67,7 @@ export default function DockerVersionDeploymentsTable(props: DockerVersionDeploy
enableServerSort: true,
isServerSorted: currentSort === id,
isServerSortedDesc: currentOrder === 'DESC',
getSortedColumn: ({ sort }: DockerVersionDeploymentsListSortBy) => {
getSortedColumn: ({ sort }: DeploymentsListSortBy) => {
if (!sort) return
setSortBy([sort, currentOrder === 'DESC' ? 'ASC' : 'DESC'])
}

View File

@ -14,6 +14,6 @@
* limitations under the License.
*/
export interface DockerVersionDeploymentsListSortBy {
export interface DeploymentsListSortBy {
sort: 'environmentName' | 'environmentType' | 'services' | 'deploymentPipeline' | 'lastModified'
}