diff --git a/src/Utilities/Helpers.js b/src/Utilities/Helpers.js index 1bfd9ea4a..dba3ef069 100644 --- a/src/Utilities/Helpers.js +++ b/src/Utilities/Helpers.js @@ -561,13 +561,19 @@ export const buildOsFilter = (osFilter = {}) => { : {}; }; -export const buildApiFilters = (patchFilters, inventoryFilters) => ({ - ...patchFilters, - ...(Array.isArray(inventoryFilters.hostGroupFilter) && inventoryFilters.hostGroupFilter.length > 0 - ? { group_name: inventoryFilters.hostGroupFilter } - : {}), - ...buildOsFilter(inventoryFilters?.osFilter), -}); +export const buildApiFilters = (patchFilters, inventoryFilters, group_name) => { + const resolvedGroupNames = + group_name ?? + (Array.isArray(inventoryFilters?.hostGroupFilter) && inventoryFilters.hostGroupFilter.length > 0 + ? inventoryFilters.hostGroupFilter + : undefined); + + return { + ...patchFilters, + ...(resolvedGroupNames?.length > 0 ? { group_name: resolvedGroupNames } : {}), + ...buildOsFilter(inventoryFilters?.osFilter), + }; +}; export const changeListParams = (oldParams, newParams) => { const newState = { ...oldParams, ...newParams }; diff --git a/src/Utilities/Helpers.test.js b/src/Utilities/Helpers.test.js index 04af6b16c..ce80e4f24 100644 --- a/src/Utilities/Helpers.test.js +++ b/src/Utilities/Helpers.test.js @@ -576,6 +576,15 @@ describe('buildApiFilters', () => { expect(buildApiFilters(patchFilters, inventoryFilters).group_name).toEqual(hostGroupFilter); }); + it('uses resolved group_name when group id passed', () => { + const inventoryFilters = { + hostGroupFilter: ['019d6966-e358-7213-b88c-95c1d63f26aa'], + }; + expect(buildApiFilters(patchFilters, inventoryFilters, ['My Workspace']).group_name).toEqual([ + 'My Workspace', + ]); + }); + it('adds a os filter when the inventory is filtered by OS', () => { const osFilter = { 'RHEL-8': { diff --git a/src/Utilities/api/api.js b/src/Utilities/api/api.js index aa074597b..1f035a80d 100644 --- a/src/Utilities/api/api.js +++ b/src/Utilities/api/api.js @@ -1,4 +1,5 @@ import { APIFactory } from '@redhat-cloud-services/javascript-clients-shared/utils'; +import apiGroupGetGroupsById from '@redhat-cloud-services/host-inventory-client/ApiGroupGetGroupsById'; import apiSystemProfileGetOperatingSystem from '@redhat-cloud-services/host-inventory-client/ApiSystemProfileGetOperatingSystem'; import axiosInstance from '../axiosInterceptors'; import { encodeApiParams, prepareEntitiesParams } from '../Helpers'; @@ -31,6 +32,7 @@ export function createApiCall( const hostInventoryApi = APIFactory( INVENTORY_API_BASE, { + apiGroupGetGroupsById, apiSystemProfileGetOperatingSystem, }, { @@ -179,5 +181,8 @@ export const exportPackageSystemsJSON = (params, packageName) => { export const getOperatingSystems = () => hostInventoryApi.apiSystemProfileGetOperatingSystem(); +export const fetchGroupsByIds = (groupIds) => + hostInventoryApi.apiGroupGetGroupsById({ groupIdList: groupIds }); + export const fetchIDs = (endpoint, queryParams) => createApiCall(endpoint, 'v3', 'get', queryParams); diff --git a/src/Utilities/hooks/Hooks.js b/src/Utilities/hooks/Hooks.js index f083ba6c3..a8fa0d235 100644 --- a/src/Utilities/hooks/Hooks.js +++ b/src/Utilities/hooks/Hooks.js @@ -16,6 +16,7 @@ import { getDefaultFilterState, mapGlobalFilters, } from '../Helpers'; +import { useHostGroupFilter } from './useHostGroupFilter'; import { intl } from '../IntlProvider'; import { createSystemsSortBy } from '../SystemsHelpers'; import { ColumnManagementModal } from '@patternfly/react-component-groups'; @@ -225,6 +226,7 @@ export const useGetEntities = ( ) => { const { id, packageName } = config || {}; const mounted = useRef(true); + const resolveHostGroupNames = useHostGroupFilter(); const getEntities = async ( _items, @@ -234,7 +236,8 @@ export const useGetEntities = ( const { selectedTags } = mapGlobalFilters(filters.tagFilters); const sort = createSystemsSortBy(orderBy, orderDirection, packageName); - const filter = buildApiFilters(patchParams.filter, filters); + const groupNames = await resolveHostGroupNames(filters?.hostGroupFilter); + const filter = buildApiFilters(patchParams.filter, filters, groupNames); const nextSelectedTags = [...activeTags, ...selectedTags]; applyInventorySnapshot && diff --git a/src/Utilities/hooks/Hooks.test.js b/src/Utilities/hooks/Hooks.test.js index 69ea66515..e55b563e8 100644 --- a/src/Utilities/hooks/Hooks.test.js +++ b/src/Utilities/hooks/Hooks.test.js @@ -21,6 +21,10 @@ jest.mock('@redhat-cloud-services/frontend-components/useChrome', () => ({ })), })); +jest.mock('./useHostGroupFilter', () => ({ + useHostGroupFilter: () => (hostGroupFilter) => Promise.resolve(hostGroupFilter ?? []), +})); + describe('Custom hooks tests', () => { it('useSetPage, should return correct offset for pagination', () => { let limit = 10; @@ -208,6 +212,8 @@ describe('Custom hooks tests', () => { const request = result.current([], params); + await Promise.resolve(); + expect(applyInventorySnapshot).toHaveBeenCalledWith({ filter: { stale: [true, false], diff --git a/src/Utilities/hooks/index.js b/src/Utilities/hooks/index.js index e2e0a66f6..520e3a884 100644 --- a/src/Utilities/hooks/index.js +++ b/src/Utilities/hooks/index.js @@ -1,4 +1,5 @@ export * from './Hooks'; +export { useHostGroupFilter } from './useHostGroupFilter'; export * from './useFeatureFlag'; export * from './useOnSelect'; export { useRemediationDataProvider } from './useRemediationDataProvider'; diff --git a/src/Utilities/hooks/useHostGroupFilter.js b/src/Utilities/hooks/useHostGroupFilter.js new file mode 100644 index 000000000..5b169bcf8 --- /dev/null +++ b/src/Utilities/hooks/useHostGroupFilter.js @@ -0,0 +1,30 @@ +import { useCallback } from 'react'; +import { fetchGroupsByIds } from '../api/api'; + +const fetchGroupNamesById = async (groupIds) => { + if (groupIds.length === 0) { + return {}; + } + + const { results = [] } = await fetchGroupsByIds(groupIds); + return Object.fromEntries( + results.filter((group) => group?.id && group?.name).map((group) => [group.id, group.name]), + ); +}; + +/** + * Resolves hostGroupFilter group IDs to names + */ +export const useHostGroupFilter = () => { + const resolveHostGroupFilter = useCallback(async (hostGroupFilter) => { + if (!Array.isArray(hostGroupFilter) || hostGroupFilter.length === 0) { + return []; + } + + const idToName = await fetchGroupNamesById(hostGroupFilter); + + return hostGroupFilter.map((value) => idToName[value] ?? value); + }, []); + + return resolveHostGroupFilter; +};