Fix icon matching in Fleet UI when apps start with similar names (#37228)

This pull request improves the logic for matching software source
strings to their corresponding icons by ensuring that more specific
matches are prioritized over more general ones. This is accomplished by
sorting the keys by length before attempting to match.

Matching logic improvements:

* Updated the `matchLoosePrefixToKey` function in
`frontend/pages/SoftwarePage/components/icons/index.ts` to sort
dictionary keys by length (longest first), ensuring that more specific
prefixes (such as "archaeology") are matched before shorter, more
general ones (like "arc").
[[1]](diffhunk://#diff-628095892e1d16090be1db6cc1a5c9cebc65248c32a8b1312385394818f2907bL477-R478)
[[2]](diffhunk://#diff-628095892e1d16090be1db6cc1a5c9cebc65248c32a8b1312385394818f2907bL487-R490)
This commit is contained in:
Allen Houchins
2025-12-13 00:26:48 -06:00
committed by GitHub
parent cbec69c649
commit a38f5826bb
@@ -474,7 +474,8 @@ export const SOFTWARE_SOURCE_TO_ICON_MAP = {
/**
* This attempts to loosely match the provided string to a key in a provided dictionary, returning the key if the
* provided string starts with the key or undefined otherwise.
* provided string starts with the key or undefined otherwise. Keys are sorted by length (longest first) to ensure
* more specific matches are checked before shorter, more general ones (e.g., "archaeology" before "arc").
*/
const matchLoosePrefixToKey = <T extends Record<string, unknown>>(
dict: T,
@@ -484,9 +485,9 @@ const matchLoosePrefixToKey = <T extends Record<string, unknown>>(
if (!s) {
return undefined;
}
const match = Object.keys(dict).find((k) =>
s.startsWith(k.trim().toLowerCase())
);
// Sort keys by length (longest first) to prioritize more specific matches
const sortedKeys = Object.keys(dict).sort((a, b) => b.length - a.length);
const match = sortedKeys.find((k) => s.startsWith(k.trim().toLowerCase()));
return match ? (match as keyof T) : undefined;
};