From 3d75b5b5ee6927a88a33ce392d43076ef3e80c58 Mon Sep 17 00:00:00 2001 From: Lucas Garfield Date: Fri, 6 Dec 2024 14:57:58 -0600 Subject: [PATCH] Utilities: Extract sorting function Extracts the function used to sort packages as a utility function so it can be reused for sorting locales as well. --- .../Locale/components/KeyboardDropDown.tsx | 39 ++----------------- .../steps/Packages/Packages.tsx | 39 ++----------------- src/Utilities/sortfn.ts | 29 ++++++++++++++ 3 files changed, 36 insertions(+), 71 deletions(-) create mode 100644 src/Utilities/sortfn.ts diff --git a/src/Components/CreateImageWizard/steps/Locale/components/KeyboardDropDown.tsx b/src/Components/CreateImageWizard/steps/Locale/components/KeyboardDropDown.tsx index 2307dfef..913b019b 100644 --- a/src/Components/CreateImageWizard/steps/Locale/components/KeyboardDropDown.tsx +++ b/src/Components/CreateImageWizard/steps/Locale/components/KeyboardDropDown.tsx @@ -19,6 +19,7 @@ import { changeKeyboard, selectKeyboard, } from '../../../../../store/wizardSlice'; +import sortfn from '../../../../../Utilities/sortfn'; import { keyboardsList } from '../keyboardsList'; const KeyboardDropDown = () => { @@ -44,47 +45,15 @@ const KeyboardDropDown = () => { setIsOpen(true); } } - setSelectOptions(filteredKeyboards.sort((a, b) => sortfn(a, b))); + setSelectOptions( + filteredKeyboards.sort((a, b) => sortfn(a, b, filterValue)) + ); // This useEffect hook should run *only* on when the filter value changes. // eslint's exhaustive-deps rule does not support this use. // eslint-disable-next-line react-hooks/exhaustive-deps }, [filterValue]); - const sortfn = (a: string, b: string) => { - const aKeyboard = a.toLowerCase(); - const bKeyboard = b.toLowerCase(); - // check exact match first - if (aKeyboard === filterValue) { - return -1; - } - if (bKeyboard === filterValue) { - return 1; - } - // check for keyboards that start with the search term - if ( - aKeyboard.startsWith(filterValue) && - !bKeyboard.startsWith(filterValue) - ) { - return -1; - } - if ( - bKeyboard.startsWith(filterValue) && - !aKeyboard.startsWith(filterValue) - ) { - return 1; - } - // if both (or neither) start with the search term - // sort alphabetically - if (aKeyboard < bKeyboard) { - return -1; - } - if (bKeyboard < aKeyboard) { - return 1; - } - return 0; - }; - const onToggle = (isOpen: boolean) => { setIsOpen(!isOpen); }; diff --git a/src/Components/CreateImageWizard/steps/Packages/Packages.tsx b/src/Components/CreateImageWizard/steps/Packages/Packages.tsx index 3c024532..c662e45c 100644 --- a/src/Components/CreateImageWizard/steps/Packages/Packages.tsx +++ b/src/Components/CreateImageWizard/steps/Packages/Packages.tsx @@ -75,6 +75,7 @@ import { removeRecommendedRepository, selectRecommendedRepositories, } from '../../../../store/wizardSlice'; +import sortfn from '../../../../Utilities/sortfn'; import useDebounce from '../../../../Utilities/useDebounce'; export type PackageRepository = 'distro' | 'custom' | 'recommended' | ''; @@ -224,40 +225,6 @@ const Packages = () => { const [createRepository, { isLoading: createLoading }] = useCreateRepositoryMutation(); - const sortfn = (a: string, b: string) => { - const aPkg = a.toLowerCase(); - const bPkg = b.toLowerCase(); - // check exact match first - if (aPkg === debouncedSearchTerm) { - return -1; - } - if (bPkg === debouncedSearchTerm) { - return 1; - } - // check for packages that start with the search term - if ( - aPkg.startsWith(debouncedSearchTerm) && - !bPkg.startsWith(debouncedSearchTerm) - ) { - return -1; - } - if ( - bPkg.startsWith(debouncedSearchTerm) && - !aPkg.startsWith(debouncedSearchTerm) - ) { - return 1; - } - // if both (or neither) start with the search term - // sort alphabetically - if (aPkg < bPkg) { - return -1; - } - if (bPkg < aPkg) { - return 1; - } - return 0; - }; - useEffect(() => { if (debouncedSearchTermIsGroup) { return; @@ -734,7 +701,7 @@ const Packages = () => { packages, toggleSelected, toggleSourceRepos, - ]).sort((a, b) => sortfn(a.name, b.name)); + ]).sort((a, b) => sortfn(a.name, b.name, debouncedSearchTerm)); const transformedGroups = useMemo(() => { let combinedGroupData: GroupWithRepositoryInfo[] = []; @@ -801,7 +768,7 @@ const Packages = () => { groups, toggleSelected, toggleSourceRepos, - ]).sort((a, b) => sortfn(a.name, b.name)); + ]).sort((a, b) => sortfn(a.name, b.name, debouncedSearchTerm)); const handleSearch = async ( event: React.FormEvent, diff --git a/src/Utilities/sortfn.ts b/src/Utilities/sortfn.ts new file mode 100644 index 00000000..855364c9 --- /dev/null +++ b/src/Utilities/sortfn.ts @@ -0,0 +1,29 @@ +const sortfn = (a: string, b: string, searchTerm: string) => { + const x = a.toLowerCase(); + const y = b.toLowerCase(); + // check exact match first + if (x === searchTerm) { + return -1; + } + if (y === searchTerm) { + return 1; + } + // check for packages that start with the search term + if (x.startsWith(searchTerm) && !y.startsWith(searchTerm)) { + return -1; + } + if (y.startsWith(searchTerm) && !x.startsWith(searchTerm)) { + return 1; + } + // if both (or neither) start with the search term + // sort alphabetically + if (x < y) { + return -1; + } + if (y < x) { + return 1; + } + return 0; +}; + +export default sortfn;