Skip to content

Commit

Permalink
Fixed ordering of catalog results with multiple types
Browse files Browse the repository at this point in the history
  • Loading branch information
ibek committed Oct 10, 2024
1 parent ff07c61 commit 0a5b5fd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 59 deletions.
27 changes: 14 additions & 13 deletions packages/ui/src/components/Catalog/Catalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,27 @@ export const Catalog: FunctionComponent<PropsWithChildren<CatalogProps>> = (prop
/** Selected Providers */
const [selectedProviders, setSelectedProviders] = useState<string[]>(providers);

/** Filter by selected group */
const filteredTilesByGroup = useMemo(() => {
const filteredTiles = useMemo(() => {

Check warning on line 45 in packages/ui/src/components/Catalog/Catalog.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/Catalog.tsx#L45

Added line #L45 was not covered by tests
return filterTiles(props.tiles, { searchTerm, searchTags: filterTags, selectedProviders });
}, [filterTags, props.tiles, searchTerm, selectedProviders]);

/** Set the tiles groups */
const tilesGroups = useMemo(() => {
return Object.entries(filteredTilesByGroup).map(([group, tiles]) => ({ name: group, count: tiles.length }));
}, [filteredTilesByGroup]);
const groups: Record<string, ITile[]> = {};
filteredTiles.forEach((tile) => {

Check warning on line 52 in packages/ui/src/components/Catalog/Catalog.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/Catalog.tsx#L51-L52

Added lines #L51 - L52 were not covered by tests
if (!groups[tile.type]) {
groups[tile.type] = [];

Check warning on line 54 in packages/ui/src/components/Catalog/Catalog.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/Catalog.tsx#L54

Added line #L54 was not covered by tests
}
groups[tile.type].push(tile);

Check warning on line 56 in packages/ui/src/components/Catalog/Catalog.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/Catalog.tsx#L56

Added line #L56 was not covered by tests
});
return Object.entries(groups).map(([group, tiles]) => ({ name: group, count: tiles.length }));

Check warning on line 58 in packages/ui/src/components/Catalog/Catalog.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/Catalog.tsx#L58

Added line #L58 was not covered by tests
}, [filteredTiles]);

const [activeGroups, setActiveGroups] = useState<string[]>(tilesGroups.map((g) => g.name));

const filteredTiles = useMemo(() => {
return Object.entries(filteredTilesByGroup).reduce((acc, [group, tiles]) => {
if (activeGroups.includes(group)) {
acc.push(...tiles);
}
return acc;
}, [] as ITile[]);
}, [activeGroups, filteredTilesByGroup]);
const filteredTilesByGroup = useMemo<ITile[]>(() => {
return filteredTiles.filter((tile) => activeGroups.includes(tile.type));

Check warning on line 64 in packages/ui/src/components/Catalog/Catalog.tsx

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/Catalog.tsx#L63-L64

Added lines #L63 - L64 were not covered by tests
}, [activeGroups, filteredTiles]);

const onFilterChange = useCallback(
(_event: unknown, value = '') => {
Expand Down Expand Up @@ -116,7 +117,7 @@ export const Catalog: FunctionComponent<PropsWithChildren<CatalogProps>> = (prop
/>
<BaseCatalog
className="catalog__base"
tiles={filteredTiles}
tiles={filteredTilesByGroup}
catalogLayout={activeLayout}
onTileClick={onTileClick}
onTagClick={onTagClick}
Expand Down
44 changes: 14 additions & 30 deletions packages/ui/src/components/Catalog/filter-tiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,62 +69,46 @@ describe('filterTiles', () => {
const options = { searchTerm: 'message' };
const result = filterTiles(tiles, options);

expect(result).toEqual({
[CatalogKind.Component]: [tilesMap.activemq],
[CatalogKind.Pattern]: [tilesMap.setBody, tilesMap.split],
[CatalogKind.Kamelet]: [tilesMap.slackSource],
});
expect(result).toEqual([tilesMap.activemq, tilesMap.setBody, tilesMap.split, tilesMap.slackSource]);
});

it('should filter tiles by provider', () => {
const options = { selectedProviders: ['Red Hat'] };
const result = filterTiles(tiles, options);

expect(result).toEqual({
[CatalogKind.Component]: [tilesMap.cron],
[CatalogKind.Pattern]: [],
[CatalogKind.Kamelet]: [],
});
expect(result).toEqual([tilesMap.cron]);
});

it('should return tiles without provider when community is selected', () => {
const options = { selectedProviders: ['Community'] };
const result = filterTiles(tiles, options);

expect(result).toEqual({
[CatalogKind.Component]: [tilesMap.activemq, tilesMap.cometd, tilesMap.hazelcast],
[CatalogKind.Pattern]: [tilesMap.setBody, tilesMap.split],
[CatalogKind.Kamelet]: [tilesMap.beerSource, tilesMap.slackSource],
});
expect(result).toEqual([
tilesMap.activemq,
tilesMap.cometd,
tilesMap.hazelcast,
tilesMap.setBody,
tilesMap.split,
tilesMap.beerSource,
tilesMap.slackSource,
]);
});

it('should filter tiles by a single tag', () => {
const options = { searchTags: ['messaging'] };
const result = filterTiles(tiles, options);
expect(result).toEqual({
[CatalogKind.Component]: [tilesMap.activemq, tilesMap.cometd, tilesMap.hazelcast],
[CatalogKind.Pattern]: [],
[CatalogKind.Kamelet]: [],
});
expect(result).toEqual([tilesMap.activemq, tilesMap.cometd, tilesMap.hazelcast]);
});

it('should filter tiles by multiple tags', () => {
const options = { searchTags: ['messaging', 'clustering'] };
const result = filterTiles(tiles, options);
expect(result).toEqual({
[CatalogKind.Component]: [tilesMap.hazelcast],
[CatalogKind.Pattern]: [],
[CatalogKind.Kamelet]: [],
});
expect(result).toEqual([tilesMap.hazelcast]);
});

it('should filter tiles by search term and tags', () => {
const options = { searchTerm: 'cr', searchTags: ['scheduling'] };
const result = filterTiles(tiles, options);
expect(result).toEqual({
[CatalogKind.Component]: [tilesMap.cron],
[CatalogKind.Pattern]: [],
[CatalogKind.Kamelet]: [],
});
expect(result).toEqual([tilesMap.cron]);
});
});
19 changes: 3 additions & 16 deletions packages/ui/src/components/Catalog/filter-tiles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { CatalogKind } from '../../models';
import { ITile } from './Catalog.models';

const checkThatArrayContainsAllTags = (tileTags: string[], searchTags: string[]) =>
Expand All @@ -7,7 +6,7 @@ const checkThatArrayContainsAllTags = (tileTags: string[], searchTags: string[])
export const filterTiles = (
tiles: ITile[],
options?: { searchTerm?: string; searchTags?: string[]; selectedProviders?: string[] },
): Record<string, ITile[]> => {
): ITile[] => {
const { searchTerm = '', searchTags = [], selectedProviders = [] } = options ?? {};
const searchTermLowercase = searchTerm.toLowerCase();

Expand Down Expand Up @@ -57,19 +56,7 @@ export const filterTiles = (
});

// Step 3: Sort the filtered tiles by score in descending order
filteredTiles.sort((a, b) => b.score - a.score);
const tilesResult: ITile[] = filteredTiles.sort((a, b) => b.score - a.score).map(({ tile }) => tile);

// Step 4: Group the sorted tiles by their type
const groupedTiles: Record<ITile['type'], ITile[]> = {};
groupedTiles[CatalogKind.Component] = [];
groupedTiles[CatalogKind.Kamelet] = [];
groupedTiles[CatalogKind.Pattern] = [];
filteredTiles.forEach(({ tile }) => {
if (!groupedTiles[tile.type]) {
groupedTiles[tile.type] = [];
}
groupedTiles[tile.type].push(tile);
});

return groupedTiles;
return tilesResult;
};

0 comments on commit 0a5b5fd

Please sign in to comment.