feat: [AH-924]: fix serach registry filter on artifact list page (#3362)

* feat: [AH-924]: fix failing tests
* feat: [AH-924]: fix serach registry filter on artifact list page
* feat: [AH-924]: support sorting and pagination in file list table
This commit is contained in:
Shivanand Sonnad 2025-01-31 08:08:12 +00:00 committed by Harness
parent c89f8516e8
commit 9224727874
7 changed files with 72 additions and 49 deletions

View File

@ -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.9.0",
"@harnessio/react-har-service-client": "^0.10.0",
"@harnessio/react-ssca-manager-client": "^0.65.0",
"@harnessio/uicore": "^4.1.2",
"@tanstack/react-query": "4.20.4",

View File

@ -19,7 +19,7 @@ import { fireEvent, render, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {
useGetAllHarnessArtifactsQuery as _useGetAllHarnessArtifactsQuery,
getAllRegistries as _getAllRegistries
useGetAllRegistriesQuery as _useGetAllRegistriesQuery
} from '@harnessio/react-har-service-client'
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
import repositoryFactory from '@ar/frameworks/RepositoryStep/RepositoryFactory'
@ -36,11 +36,16 @@ import {
} from './__mockData__'
const useGetAllHarnessArtifactsQuery = _useGetAllHarnessArtifactsQuery as jest.Mock
const getAllRegistries = _getAllRegistries as jest.Mock
const useGetAllRegistriesQuery = _useGetAllRegistriesQuery as jest.Mock
jest.mock('@harnessio/react-har-service-client', () => ({
useGetAllHarnessArtifactsQuery: jest.fn(),
getAllRegistries: jest.fn()
useGetAllRegistriesQuery: jest.fn().mockImplementation(() => ({
isFetching: false,
data: mockGetAllRegistriesResponse,
refetch: jest.fn(),
error: null
}))
}))
describe('Test Artifact List Page', () => {
@ -52,12 +57,10 @@ describe('Test Artifact List Page', () => {
useGetAllHarnessArtifactsQuery.mockImplementation(() => {
return mockUseGetAllHarnessArtifactsQueryResponse
})
getAllRegistries.mockImplementation(() => new Promise(resolve => resolve(mockGetAllRegistriesResponse)))
})
test('Should render proper empty list if artifacts reponse is empty', async () => {
useGetAllHarnessArtifactsQuery.mockImplementationOnce(() => mockEmptyUseGetAllHarnessArtifactsQueryResponse)
getAllRegistries.mockImplementationOnce(() => new Promise(resolve => resolve(mockEmptyGetAllRegistriesResponse)))
const { container, getByText } = render(
<ArTestWrapper>
@ -197,7 +200,7 @@ describe('Test Artifact List Page', () => {
)
useGetAllHarnessArtifactsQuery.mockImplementationOnce(() => mockEmptyUseGetAllHarnessArtifactsQueryResponse)
getAllRegistries.mockImplementationOnce(() => new Promise(resolve => resolve(mockEmptyGetAllRegistriesResponse)))
useGetAllRegistriesQuery.mockImplementationOnce(() => mockEmptyGetAllRegistriesResponse)
const latestVersionTab = getByText('artifactList.table.latestVersions')
await userEvent.click(latestVersionTab)

View File

@ -15,12 +15,13 @@
*/
import React, { useMemo } from 'react'
import { Menu, MenuItem } from '@blueprintjs/core'
import type { SelectOption } from '@harnessio/uicore'
import { MultiSelectDropDown } from '@harnessio/uicore'
import { getAllRegistries } from '@harnessio/react-har-service-client'
import { useGetAllRegistriesQuery } from '@harnessio/react-har-service-client'
import { getErrorInfoFromErrorObject, MultiSelectDropDown } from '@harnessio/uicore'
import { useStrings } from '@ar/frameworks/strings'
import { useGetSpaceRef } from '@ar/hooks'
import { useStrings } from '@ar/frameworks/strings'
export interface RepositorySelectorProps {
value?: string[]
@ -32,25 +33,31 @@ export default function RepositorySelector(props: RepositorySelectorProps): JSX.
const { getString } = useStrings()
const spaceRef = useGetSpaceRef()
const queryRepositories = async (): Promise<SelectOption[]> => {
return getAllRegistries({
space_ref: spaceRef,
queryParams: {
size: 10,
page: 0,
search_term: query
}
})
.then(result => {
const selectItems = result?.content?.data?.registries?.map(item => {
return { label: item.identifier, value: item.identifier }
}) as SelectOption[]
return selectItems || []
})
.catch(() => {
return []
})
}
const { data, isFetching, error } = useGetAllRegistriesQuery({
space_ref: spaceRef,
queryParams: {
size: 10,
page: 0,
search_term: query
}
})
const items: SelectOption[] = useMemo(() => {
if (isFetching) {
return [{ label: getString('loading'), value: '-1', disabled: true }]
}
if (error) {
return [{ label: getErrorInfoFromErrorObject(error), value: '-1', disabled: true }]
}
if (data?.content.data.registries.length === 0) {
return [{ label: getString('noResultsFound'), value: '-1', disabled: true }]
}
return (
data?.content.data.registries?.map(item => {
return { label: item.identifier, value: item.identifier }
}) || []
)
}, [data, isFetching, error])
const selectedValues = useMemo(() => {
if (Array.isArray(props.value)) {
@ -74,12 +81,27 @@ export default function RepositorySelector(props: RepositorySelectorProps): JSX.
props.onChange(options.map(each => each.value as string))
}}
value={selectedValues}
items={queryRepositories}
items={items}
usePortal={true}
query={query}
allowSearch
onQueryChange={setQuery}
expandingSearchInputProps={{
defaultValue: query,
onChange: q => setQuery(q)
}}
itemListRenderer={itemListProps => {
return (
<Menu>
{itemListProps.items.map((item, idx) => {
if (item.disabled) {
return <MenuItem key={item.label} text={item.label} disabled />
}
return itemListProps.renderItem(item, idx)
})}
</Menu>
)
}}
placeholder={getString('artifactList.table.allRepositories')}
onPopoverClose={() => setQuery('')}
/>
)
}

View File

@ -37,7 +37,7 @@ export default function GenericArtifactDetailsPage() {
const pathParams = useDecodedParams<VersionDetailsPathParams>()
const queryParamOptions = useArtifactFileListQueryParamOptions()
const queryParams = useQueryParams<ArtifactFileListPageQueryParams>(queryParamOptions)
const { searchTerm, page, size, sort } = queryParams
const { page, size, sort } = queryParams
const [sortField, sortOrder] = sort || []
@ -51,11 +51,10 @@ export default function GenericArtifactDetailsPage() {
artifact: encodeRef(pathParams.artifactIdentifier),
version: pathParams.versionIdentifier,
queryParams: {
searchTerm,
page,
size,
sortField,
sortOrder
sort_field: sortField,
sort_order: sortOrder
}
})
const response = data?.content

View File

@ -37,7 +37,7 @@ export default function MavenArtifactDetailsPage() {
const pathParams = useDecodedParams<VersionDetailsPathParams>()
const queryParamOptions = useArtifactFileListQueryParamOptions()
const queryParams = useQueryParams<ArtifactFileListPageQueryParams>(queryParamOptions)
const { searchTerm, page, size, sort } = queryParams
const { page, size, sort } = queryParams
const [sortField, sortOrder] = sort || []
@ -51,11 +51,10 @@ export default function MavenArtifactDetailsPage() {
artifact: encodeRef(pathParams.artifactIdentifier),
version: pathParams.versionIdentifier,
queryParams: {
searchTerm,
page,
size,
sortField,
sortOrder
sort_field: sortField,
sort_order: sortOrder
}
})
const response = data?.content

View File

@ -51,12 +51,12 @@ export default function ArtifactFileListTable(props: ArtifactFileListTableProps)
const { useDefaultPaginationProps } = useParentHooks()
const { getString } = useStrings()
const { files } = data
const { files, itemCount = 0, pageCount = 0, pageIndex, pageSize = 0 } = data
const paginationProps = useDefaultPaginationProps({
itemCount: 0,
pageSize: 100,
pageCount: 1,
pageIndex: 1,
itemCount,
pageSize,
pageCount,
pageIndex,
gotoPage,
onPageSizeChange
})

View File

@ -1945,10 +1945,10 @@
yargs "^17.6.2"
zod "^3.19.1"
"@harnessio/react-har-service-client@^0.9.0":
version "0.9.0"
resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.9.0.tgz#98bea7fb355769a647d8a02f35d59e56dac927ca"
integrity sha512-3UEWYj++l0tr6npVXG6IuvkLXqNe4t64FLyt28P5JaAre79HErBNq6P40/q7I9PU6mgx96oHHuUKpIajauteJw==
"@harnessio/react-har-service-client@^0.10.0":
version "0.10.0"
resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.10.0.tgz#84a9a89ec3f02b35313dae02857789ec25a095dc"
integrity sha512-TC84QK0mas2F3dtN7EK4yJkjJYPCq0uEtXCdMCyvX36Mw/4mY+pEcbfhQhaP+cugqWJT2/eZ21TrPrx07rG/ig==
dependencies:
"@harnessio/oats-cli" "^3.0.0"