Skip to content

Commit

Permalink
Enhance filterTiles with scoring, filtering, and sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
ibek committed Oct 9, 2024
1 parent f95f50e commit ff07c61
Showing 1 changed file with 62 additions and 33 deletions.
95 changes: 62 additions & 33 deletions packages/ui/src/components/Catalog/filter-tiles.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CatalogKind } from '../../models';
import { ITile } from './Catalog.models';

const checkThatArrayContainsAllTags = (tileTags: string[], searchTags: string[]) =>
Expand All @@ -10,37 +11,65 @@ export const filterTiles = (
const { searchTerm = '', searchTags = [], selectedProviders = [] } = options ?? {};
const searchTermLowercase = searchTerm.toLowerCase();

return tiles.reduce(
(acc, tile) => {
/** Filter by selected tags */
const doesTagsMatches = searchTags.length ? checkThatArrayContainsAllTags(tile.tags, searchTags) : true;

/** Filter by providers */
let doesProviderMatch = true;
if (selectedProviders.length) {
doesProviderMatch =
tile.provider === undefined
? selectedProviders.includes('Community')
: selectedProviders.includes(tile.provider);
}

/** Determine whether the tile should be included in the filtered list */
const shouldInclude =
doesTagsMatches &&
doesProviderMatch &&
(!searchTermLowercase ||
tile.name.toLowerCase().includes(searchTermLowercase) ||
tile.title.toLowerCase().includes(searchTermLowercase) ||
tile.description?.toLowerCase().includes(searchTermLowercase) ||
tile.tags.some((tag) => tag.toLowerCase().includes(searchTermLowercase)));

acc[tile.type] = acc[tile.type] ?? [];
if (shouldInclude) {
acc[tile.type].push(tile);
}

return acc;
},
{} as Record<ITile['type'], ITile[]>,
);
// Step 1: Score each tile based on how well it matches the search term
const scoredTiles = tiles.map((tile) => {
let score = 0;

// Score based on name
const nameLower = tile.name.toLowerCase();
if (nameLower.startsWith(searchTermLowercase)) {
score += 100;
} else if (nameLower.includes(searchTermLowercase)) {
score += 40;

Check warning on line 23 in packages/ui/src/components/Catalog/filter-tiles.ts

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/filter-tiles.ts#L23

Added line #L23 was not covered by tests
}

// Score based on title
if (tile.title?.toLowerCase().includes(searchTermLowercase)) {
score += 40;
}

// Score based on description
if (tile.description?.toLowerCase().includes(searchTermLowercase)) {
score += 10;
}

return { tile, score };
});

// Step 2: Filter tiles based on score, tags, and providers
const filteredTiles = scoredTiles.filter(({ tile, score }) => {
// Exclude tiles with no match
if (score <= 0) return false;

// Filter by selected tags
const doesTagsMatch = searchTags.length ? checkThatArrayContainsAllTags(tile.tags, searchTags) : true;

// Filter by selected providers
let doesProviderMatch = true;
if (selectedProviders.length) {
doesProviderMatch =
tile.provider === undefined
? selectedProviders.includes('Community')
: selectedProviders.includes(tile.provider);
}

return doesTagsMatch && doesProviderMatch;
});

// Step 3: Sort the filtered tiles by score in descending order
filteredTiles.sort((a, b) => b.score - a.score);

// 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] = [];

Check warning on line 69 in packages/ui/src/components/Catalog/filter-tiles.ts

View check run for this annotation

Codecov / codecov/patch

packages/ui/src/components/Catalog/filter-tiles.ts#L69

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

return groupedTiles;
};

0 comments on commit ff07c61

Please sign in to comment.