mirror of
https://github.com/harness/drone.git
synced 2025-05-05 23:42:57 +00:00
feat: [AH-620]: support generic artifact details view (#3173)
* feat: [AH-620]: support generic artifact details view
This commit is contained in:
parent
aaebea0c5d
commit
2ced78f102
@ -51,7 +51,7 @@
|
||||
"@codemirror/view": "^6.9.6",
|
||||
"@harnessio/design-system": "^2.1.1",
|
||||
"@harnessio/icons": "^2.1.9",
|
||||
"@harnessio/react-har-service-client": "^0.2.0",
|
||||
"@harnessio/react-har-service-client": "^0.3.0",
|
||||
"@harnessio/react-ssca-manager-client": "^0.65.0",
|
||||
"@harnessio/uicore": "^4.1.2",
|
||||
"@tanstack/react-query": "4.20.4",
|
||||
|
@ -25,6 +25,7 @@ import { String } from '@ar/frameworks/strings'
|
||||
import { VersionDetailsTab } from '../components/VersionDetailsTabs/constants'
|
||||
import GenericVersionHeader from './GenericVersionHeader'
|
||||
import GenericOverviewPage from './pages/overview/OverviewPage'
|
||||
import GenericArtifactDetailsPage from './pages/artifact-details/GenericArtifactDetailsPage'
|
||||
|
||||
export class GenericVersionType extends VersionStep<ArtifactVersionSummary> {
|
||||
protected packageType = RepositoryPackageType.GENERIC
|
||||
@ -48,7 +49,7 @@ export class GenericVersionType extends VersionStep<ArtifactVersionSummary> {
|
||||
case VersionDetailsTab.OVERVIEW:
|
||||
return <GenericOverviewPage />
|
||||
case VersionDetailsTab.ARTIFACT_DETAILS:
|
||||
return <></>
|
||||
return <GenericArtifactDetailsPage />
|
||||
case VersionDetailsTab.DEPLOYMENTS:
|
||||
return <></>
|
||||
case VersionDetailsTab.OSS:
|
||||
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 { Page } from '@harnessio/uicore'
|
||||
import { useGetArtifactFilesQuery } from '@harnessio/react-har-service-client'
|
||||
|
||||
import { DEFAULT_PAGE_INDEX } from '@ar/constants'
|
||||
import type { VersionDetailsPathParams } from '@ar/routes/types'
|
||||
import { useDecodedParams, useGetSpaceRef, useParentHooks } from '@ar/hooks'
|
||||
import {
|
||||
type ArtifactFileListPageQueryParams,
|
||||
useArtifactFileListQueryParamOptions
|
||||
} from '@ar/pages/version-details/components/ArtifactFileListTable/utils'
|
||||
import ArtifactFileListTable from '@ar/pages/version-details/components/ArtifactFileListTable/ArtifactFileListTable'
|
||||
import versionDetailsPageCss from '../../styles.module.scss'
|
||||
|
||||
export default function GenericArtifactDetailsPage() {
|
||||
const registryRef = useGetSpaceRef()
|
||||
const { useQueryParams, useUpdateQueryParams } = useParentHooks()
|
||||
const { updateQueryParams } = useUpdateQueryParams<Partial<ArtifactFileListPageQueryParams>>()
|
||||
|
||||
const pathParams = useDecodedParams<VersionDetailsPathParams>()
|
||||
const queryParamOptions = useArtifactFileListQueryParamOptions()
|
||||
const queryParams = useQueryParams<ArtifactFileListPageQueryParams>(queryParamOptions)
|
||||
const { searchTerm, page, size, sort } = queryParams
|
||||
|
||||
const [sortField, sortOrder] = sort || []
|
||||
|
||||
const {
|
||||
isFetching: loading,
|
||||
error,
|
||||
data,
|
||||
refetch
|
||||
} = useGetArtifactFilesQuery({
|
||||
registry_ref: registryRef,
|
||||
artifact: pathParams.artifactIdentifier,
|
||||
version: pathParams.versionIdentifier,
|
||||
queryParams: {
|
||||
searchTerm,
|
||||
page,
|
||||
size,
|
||||
sortField,
|
||||
sortOrder
|
||||
}
|
||||
})
|
||||
const response = data?.content
|
||||
|
||||
return (
|
||||
<Page.Body
|
||||
className={versionDetailsPageCss.pageBody}
|
||||
loading={loading}
|
||||
error={error?.message || error}
|
||||
retryOnError={() => refetch()}>
|
||||
{response && (
|
||||
<ArtifactFileListTable
|
||||
data={response}
|
||||
gotoPage={pageNumber => updateQueryParams({ page: pageNumber })}
|
||||
setSortBy={sortArr => {
|
||||
updateQueryParams({ sort: sortArr, page: DEFAULT_PAGE_INDEX })
|
||||
}}
|
||||
sortBy={sort}
|
||||
/>
|
||||
)}
|
||||
</Page.Body>
|
||||
)
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.table {
|
||||
--typography-size: 12px;
|
||||
--typography-weight: 400;
|
||||
--line-height: 20px;
|
||||
padding: var(--spacing-large);
|
||||
|
||||
[role='cell'],
|
||||
[role='columnheader'] {
|
||||
width: auto !important;
|
||||
padding-right: var(--spacing-large);
|
||||
}
|
||||
|
||||
div[class*='TableV2--cells'],
|
||||
div[class*='TableV2--header'] {
|
||||
display: grid !important;
|
||||
width: 100%; /* Ensure the container doesn't exceed 100% width */
|
||||
grid-template-columns: minmax(var(--har-table-name-column-min-width), 15rem) 80px 350px minmax(0, 1fr) 100px;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
// This is an auto-generated file
|
||||
export declare const table: string
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 classNames from 'classnames'
|
||||
import type { Column } from 'react-table'
|
||||
import { type PaginationProps, TableV2 } from '@harnessio/uicore'
|
||||
import type { FileDetail, FileDetailResponseResponse } from '@harnessio/react-har-service-client'
|
||||
|
||||
import { useParentHooks } from '@ar/hooks'
|
||||
import { useStrings } from '@ar/frameworks/strings'
|
||||
import {
|
||||
FileChecksumListCell,
|
||||
FileCreatedCell,
|
||||
FileDownloadCommandCell,
|
||||
FileNameCell,
|
||||
FileSizeCell
|
||||
} from './ArtifactListTableCells'
|
||||
|
||||
import css from './ArtifactFileListTable.module.scss'
|
||||
|
||||
export interface FileListSortBy {
|
||||
sort: 'name' | 'size' | 'created'
|
||||
}
|
||||
|
||||
interface ArtifactFileListTableProps {
|
||||
data: FileDetailResponseResponse
|
||||
gotoPage: (pageNumber: number) => void
|
||||
onPageSizeChange?: PaginationProps['onPageSizeChange']
|
||||
setSortBy: (sortBy: string[]) => void
|
||||
sortBy: string[]
|
||||
minimal?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function ArtifactFileListTable(props: ArtifactFileListTableProps): JSX.Element {
|
||||
const { data, gotoPage, onPageSizeChange, sortBy, setSortBy, className } = props
|
||||
const { useDefaultPaginationProps } = useParentHooks()
|
||||
const { getString } = useStrings()
|
||||
|
||||
const { files } = data
|
||||
const paginationProps = useDefaultPaginationProps({
|
||||
itemCount: 0,
|
||||
pageSize: 100,
|
||||
pageCount: 1,
|
||||
pageIndex: 1,
|
||||
gotoPage,
|
||||
onPageSizeChange
|
||||
})
|
||||
|
||||
const [currentSort, currentOrder] = sortBy
|
||||
|
||||
const columns: Column<FileDetail>[] = React.useMemo(() => {
|
||||
const getServerSortProps = (id: string) => {
|
||||
return {
|
||||
enableServerSort: true,
|
||||
isServerSorted: currentSort === id,
|
||||
isServerSortedDesc: currentOrder === 'DESC',
|
||||
getSortedColumn: ({ sort }: FileListSortBy) => {
|
||||
setSortBy([sort, currentOrder === 'DESC' ? 'ASC' : 'DESC'])
|
||||
}
|
||||
}
|
||||
}
|
||||
return [
|
||||
{
|
||||
Header: getString('versionDetails.artifactFiles.table.columns.name'),
|
||||
accessor: 'name',
|
||||
Cell: FileNameCell,
|
||||
serverSortProps: getServerSortProps('name'),
|
||||
width: ''
|
||||
},
|
||||
{
|
||||
Header: getString('versionDetails.artifactFiles.table.columns.size'),
|
||||
accessor: 'size',
|
||||
Cell: FileSizeCell,
|
||||
serverSortProps: getServerSortProps('size')
|
||||
},
|
||||
{
|
||||
Header: getString('versionDetails.artifactFiles.table.columns.checksum'),
|
||||
accessor: 'checksums',
|
||||
Cell: FileChecksumListCell,
|
||||
disableSortBy: true
|
||||
},
|
||||
{
|
||||
Header: getString('versionDetails.artifactFiles.table.columns.downloadCommand'),
|
||||
accessor: 'downloadCommand',
|
||||
Cell: FileDownloadCommandCell,
|
||||
disableSortBy: true
|
||||
},
|
||||
{
|
||||
Header: getString('versionDetails.artifactFiles.table.columns.created'),
|
||||
accessor: 'createdAt',
|
||||
Cell: FileCreatedCell,
|
||||
serverSortProps: getServerSortProps('createdAt')
|
||||
}
|
||||
].filter(Boolean) as unknown as Column<FileDetail>[]
|
||||
}, [currentOrder, currentSort, getString])
|
||||
|
||||
return (
|
||||
<TableV2
|
||||
className={classNames(css.table, className)}
|
||||
columns={columns}
|
||||
data={files as FileDetail[]}
|
||||
pagination={paginationProps}
|
||||
sortable
|
||||
/>
|
||||
)
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 { Layout } from '@harnessio/uicore'
|
||||
import type { FileDetail } from '@harnessio/react-har-service-client'
|
||||
import type { Cell, CellValue, ColumnInstance, Renderer, Row, TableInstance } from 'react-table'
|
||||
|
||||
import { killEvent } from '@ar/common/utils'
|
||||
import { useStrings } from '@ar/frameworks/strings'
|
||||
import TableCells from '@ar/components/TableCells/TableCells'
|
||||
import CommandBlock from '@ar/components/CommandBlock/CommandBlock'
|
||||
|
||||
type CellTypeWithActions<D extends Record<string, any>, V = any> = TableInstance<D> & {
|
||||
column: ColumnInstance<D>
|
||||
row: Row<D>
|
||||
cell: Cell<D, V>
|
||||
value: CellValue<V>
|
||||
}
|
||||
|
||||
type CellType = Renderer<CellTypeWithActions<FileDetail>>
|
||||
|
||||
export const FileNameCell: CellType = ({ value }) => {
|
||||
return <TableCells.TextCell value={value} />
|
||||
}
|
||||
|
||||
export const FileSizeCell: CellType = ({ value }) => {
|
||||
return <TableCells.SizeCell value={value} />
|
||||
}
|
||||
|
||||
export const FileChecksumListCell: CellType = ({ value }) => {
|
||||
const { getString } = useStrings()
|
||||
if (Array.isArray(value) && value.length) {
|
||||
return (
|
||||
<Layout.Vertical spacing="xsmall">
|
||||
{value.map(each => (
|
||||
<TableCells.TextCell key={each} value={each} />
|
||||
))}
|
||||
</Layout.Vertical>
|
||||
)
|
||||
}
|
||||
return <TableCells.TextCell value={getString('na')} />
|
||||
}
|
||||
|
||||
export const FileCreatedCell: CellType = ({ value }) => {
|
||||
return <TableCells.LastModifiedCell value={value} />
|
||||
}
|
||||
|
||||
export const FileDownloadCommandCell: CellType = ({ value }) => {
|
||||
const { getString } = useStrings()
|
||||
if (!value) return <TableCells.TextCell value={getString('na')} />
|
||||
return <CommandBlock noWrap commandSnippet={value} allowCopy onCopy={killEvent} />
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 { useMemo } from 'react'
|
||||
|
||||
import { useParentHooks } from '@ar/hooks'
|
||||
import { DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE, DEFAULT_PIPELINE_LIST_TABLE_SORT } from '@ar/constants'
|
||||
import type { UseQueryParamsOptions } from '@ar/__mocks__/hooks'
|
||||
|
||||
export type ArtifactFileListPageQueryParams = {
|
||||
page: number
|
||||
size: number
|
||||
sort: string[]
|
||||
searchTerm?: string
|
||||
}
|
||||
|
||||
export const useArtifactFileListQueryParamOptions = (): UseQueryParamsOptions<ArtifactFileListPageQueryParams> => {
|
||||
const { useQueryParamsOptions } = useParentHooks()
|
||||
const _options = useQueryParamsOptions(
|
||||
{
|
||||
page: DEFAULT_PAGE_INDEX,
|
||||
size: DEFAULT_PAGE_SIZE,
|
||||
sort: DEFAULT_PIPELINE_LIST_TABLE_SORT
|
||||
},
|
||||
{ ignoreEmptyString: false }
|
||||
)
|
||||
const options = useMemo(() => ({ ..._options, strictNullHandling: true }), [_options])
|
||||
|
||||
return options
|
||||
}
|
@ -73,3 +73,11 @@ deploymentsTable:
|
||||
triggeredBy: Triggered At
|
||||
infra: Infrastructure
|
||||
instanceCount: Instance Count
|
||||
artifactFiles:
|
||||
table:
|
||||
columns:
|
||||
name: Name
|
||||
size: Size
|
||||
checksum: Checksum
|
||||
downloadCommand: Download Command
|
||||
created: Created
|
||||
|
@ -152,6 +152,11 @@ export interface StringsMap {
|
||||
'versionDetails.artifactDetails.layers.size': string
|
||||
'versionDetails.artifactDetails.tabs.layers': string
|
||||
'versionDetails.artifactDetails.tabs.manifest': string
|
||||
'versionDetails.artifactFiles.table.columns.checksum': string
|
||||
'versionDetails.artifactFiles.table.columns.created': string
|
||||
'versionDetails.artifactFiles.table.columns.downloadCommand': string
|
||||
'versionDetails.artifactFiles.table.columns.name': string
|
||||
'versionDetails.artifactFiles.table.columns.size': string
|
||||
'versionDetails.cards.container.title': string
|
||||
'versionDetails.cards.container.versionDigest': string
|
||||
'versionDetails.cards.deploymentsCard.buildTitle': string
|
||||
|
@ -1945,10 +1945,10 @@
|
||||
yargs "^17.6.2"
|
||||
zod "^3.19.1"
|
||||
|
||||
"@harnessio/react-har-service-client@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.2.0.tgz#83f1f793c18e0e796ba7b1652801bfd676854963"
|
||||
integrity sha512-W4GSiBTiI6DOCo9eqJPmxEf9I7PJA01AxAf9TrQ21fxFDuZbSk0c3YvZFz7INiHGUnNrB5QTLVgCVZRvelOkgw==
|
||||
"@harnessio/react-har-service-client@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.3.0.tgz#b434034093c6619effe42720c7c078d18a9ecc50"
|
||||
integrity sha512-+pFkxlUUM9CEkB60kx3SjppCdHdycfJhRN6t4p1R0M/n93dQLrdI0uHkoDZEeWb0o1Q0oQ21pkwTYktQr24E3g==
|
||||
dependencies:
|
||||
"@harnessio/oats-cli" "^3.0.0"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user