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.
This commit is contained in:
Lucas Garfield 2024-12-06 14:57:58 -06:00 committed by Lucas Garfield
parent 4899553151
commit 3d75b5b5ee
3 changed files with 36 additions and 71 deletions

View file

@ -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);
};

View file

@ -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<HTMLInputElement>,

29
src/Utilities/sortfn.ts Normal file
View file

@ -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;