diff --git a/src/components/SettingsHeader.tsx b/src/components/SettingsHeader.tsx index eece85c..fea40c8 100644 --- a/src/components/SettingsHeader.tsx +++ b/src/components/SettingsHeader.tsx @@ -35,6 +35,7 @@ export function SettingsHeader({ setIsLoading, sortBy, setSortBy, + customSearchEnabled, }: { setDragging: undefined | ((dragging: boolean) => void); openModal: undefined | (() => void); @@ -51,6 +52,7 @@ export function SettingsHeader({ setIsLoading: (isLoading: boolean) => void; sortBy: string; setSortBy: undefined | ((sortBy: string) => void); + customSearchEnabled: boolean; }) { const { isMobile, theme } = useCommonHooks(); const [disabled, setDisabled] = useState(false); @@ -245,21 +247,25 @@ export function SettingsHeader({ > {'Oldest'} - { - setSortBy('Custom'); - }} - style={{ - color: - sortBy === 'Custom' - ? 'var(--mantine-color-background-0)' - : 'var(--mantine-color-primary-0)', - backgroundColor: - sortBy === 'Custom' ? 'var(--mantine-color-primary-0)' : undefined, - }} - > - {'Custom'} - + {customSearchEnabled && ( + { + setSortBy('Custom'); + }} + style={{ + color: + sortBy === 'Custom' + ? 'var(--mantine-color-background-0)' + : 'var(--mantine-color-primary-0)', + backgroundColor: + sortBy === 'Custom' + ? 'var(--mantine-color-primary-0)' + : undefined, + }} + > + {'Custom'} + + )} )} diff --git a/src/pages/settings/components/Applications/Applications.tsx b/src/pages/settings/components/Applications/Applications.tsx index d2ff177..e2efa4b 100644 --- a/src/pages/settings/components/Applications/Applications.tsx +++ b/src/pages/settings/components/Applications/Applications.tsx @@ -166,6 +166,7 @@ export function Applications() { setIsLoading={setIsLoading} sortBy={sortBy} setSortBy={setSortBy} + customSearchEnabled /> {modalOpened && ( ([]); const [groupList, setGroupList] = useState([]); const { isMobile, reorder, theme } = useCommonHooks(); @@ -71,6 +72,7 @@ export function Bookmarks() { const foundGroups: BookmarkGroup[] = groupData?.filter((a: BookmarkGroup) => a.categoryName.toLowerCase().includes((debouncedGroupSearch as string).toLowerCase()), ); + const handleClose = () => { closeModal(); form.reset(); @@ -99,15 +101,44 @@ export function Bookmarks() { useEffect(() => { if (groupData && groupsIsFetched) { const groupList = [...new Set([...foundBookmarkGroups, ...foundGroups])].sort( - (a: BookmarkGroup, b: BookmarkGroup) => - a.categoryIndex > b.categoryIndex ? 1 : -1, + (a: BookmarkGroup, b: BookmarkGroup) => { + if (!dragging) { + switch (sortBy) { + case 'A>Z': + return a.categoryName.toLocaleLowerCase() > + b.categoryName.toLocaleLowerCase() + ? 1 + : -1; + case 'Z>A': + return a.categoryName.toLocaleLowerCase() < + b.categoryName.toLocaleLowerCase() + ? 1 + : -1; + case 'Newest': + if (a.id && b.id) { + return a.id < b.id ? 1 : -1; + } + return -1; + case 'Oldest': + if (a.id && b.id) { + return a.id > b.id ? 1 : -1; + } + return -1; + case 'Custom': + return a.categoryIndex > b.categoryIndex ? 1 : -1; + default: + return 0; + } + } + return a.categoryIndex > b.categoryIndex ? 1 : -1; + }, ); setGroups(groupList); } if (debouncedGroupSearch === searchValue) { setIsLoading(false); } - }, [groupData, groupsIsFetched, debouncedGroupSearch]); + }, [groupData, groupsIsFetched, debouncedGroupSearch, sortBy, dragging]); useEffect(() => { if (groupList.length > 0 && groupList !== groups) { @@ -221,8 +252,9 @@ export function Bookmarks() { searchPlaceholder={'Search Bookmarks...'} isLoading={isLoading} setIsLoading={setIsLoading} - sortBy={''} - setSortBy={undefined} + sortBy={sortBy} + setSortBy={setSortBy} + customSearchEnabled /> {dragging ? ( diff --git a/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx b/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx index 019e750..9221b3b 100644 --- a/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx +++ b/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx @@ -23,6 +23,7 @@ import DebouncedGuacamoleClient from './DebouncedGuacamoleClient'; import GuacamoleClientSettingsItem from './GuacamoleClientSettingsItem'; export function GuacamoleClients() { + const [sortBy, setSortBy] = useState('Oldest'); const defaultGuacamoleClient: GuacamoleClient = { id: undefined, clientName: '', @@ -46,13 +47,40 @@ export function GuacamoleClients() { endpoint: endpoint, }); const guacamoleClients: GuacamoleClient[] = - guacamoleClientsData.filter( - (a: GuacamoleClient) => - a.clientName.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || - a.clientIdentifier - .toLowerCase() - .includes((debouncedSearch as string).toLowerCase()), - ) || []; + guacamoleClientsData + .filter( + (a: GuacamoleClient) => + a.clientName + .toLowerCase() + .includes((debouncedSearch as string).toLowerCase()) || + a.clientIdentifier + .toLowerCase() + .includes((debouncedSearch as string).toLowerCase()), + ) + .sort((a: GuacamoleClient, b: GuacamoleClient) => { + switch (sortBy) { + case 'A>Z': + return a.clientName.toLocaleLowerCase() > b.clientName.toLocaleLowerCase() + ? 1 + : -1; + case 'Z>A': + return a.clientName.toLocaleLowerCase() < b.clientName.toLocaleLowerCase() + ? 1 + : -1; + case 'Newest': + if (a.id && b.id) { + return a.id < b.id ? 1 : -1; + } + return -1; + case 'Oldest': + if (a.id && b.id) { + return a.id > b.id ? 1 : -1; + } + return -1; + default: + return 0; + } + }) || []; const { mutateAsync } = useMutationAPI(); const { isMobile, theme } = useCommonHooks(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); @@ -210,8 +238,9 @@ export function GuacamoleClients() { searchPlaceholder={'Search Clients...'} isLoading={isLoading} setIsLoading={setIsLoading} - sortBy={''} - setSortBy={undefined} + sortBy={sortBy} + setSortBy={setSortBy} + customSearchEnabled={false} /> (''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const { isMobile, theme } = useCommonHooks(); const { mutateAsync } = useMutationAPI(); const messages: Message[] = - messageData?.filter((m: Message) => - m.message.toLowerCase().includes((debouncedSearch as string).toLowerCase()), - ) || []; + messageData + ?.filter((m: Message) => + m.message.toLowerCase().includes((debouncedSearch as string).toLowerCase()), + ) + .sort((a: Message, b: Message) => { + switch (sortBy) { + case 'A>Z': + return a.message.toLocaleLowerCase() > b.message.toLocaleLowerCase() ? 1 : -1; + case 'Z>A': + return a.message.toLocaleLowerCase() < b.message.toLocaleLowerCase() ? 1 : -1; + case 'Newest': + if (a.id && b.id) { + return a.id < b.id ? 1 : -1; + } + return -1; + case 'Oldest': + if (a.id && b.id) { + return a.id > b.id ? 1 : -1; + } + return -1; + default: + return 0; + } + }) || []; const [message, setMessage] = useState({}); const [debounced] = useDebouncedValue(message, 1000); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); @@ -82,8 +104,9 @@ export function Messages() { searchPlaceholder={'Search Messages...'} isLoading={isLoading} setIsLoading={setIsLoading} - sortBy={''} - setSortBy={undefined} + sortBy={sortBy} + setSortBy={setSortBy} + customSearchEnabled={false} /> {modalOpened && ( (a.prefix > b.prefix ? 1 : -1)) ?? []; + .sort((a: Provider, b: Provider) => { + switch (sortBy) { + case 'A>Z': + return a.name.toLocaleLowerCase() > b.name.toLocaleLowerCase() ? 1 : -1; + case 'Z>A': + return a.name.toLocaleLowerCase() < b.name.toLocaleLowerCase() ? 1 : -1; + case 'Newest': + if (a.id && b.id) { + return a.id < b.id ? 1 : -1; + } + return -1; + case 'Oldest': + if (a.id && b.id) { + return a.id > b.id ? 1 : -1; + } + return -1; + default: + return 0; + } + }) ?? []; const { isMobile, theme, iconFilter } = useCommonHooks(); const { mutateAsync } = useMutationAPI(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); @@ -281,8 +301,9 @@ export function SearchProviders() { searchPlaceholder={'Search Providers...'} isLoading={isLoading} setIsLoading={setIsLoading} - sortBy={''} - setSortBy={undefined} + sortBy={sortBy} + setSortBy={setSortBy} + customSearchEnabled={false} /> { - mutateAsync({ + void mutateAsync({ method: selectedPlaylist?.id === undefined ? 'POST' : 'PATCH', endpoint: themePlaylistsEndpoint, body: selectedPlaylist ?? {}, @@ -162,6 +162,9 @@ export function ThemePlaylists() { searchPlaceholder={'Search Theme Playlists...'} isLoading={isLoading} setIsLoading={setIsLoading} + sortBy={''} + setSortBy={undefined} + customSearchEnabled={false} /> (''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); - const allThemes: Theme[] = allThemeData?.filter((a: Theme) => - a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()), - ); + const allThemes: Theme[] = allThemeData + ?.filter((a: Theme) => + a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()), + ) + .sort((a: Theme, b: Theme) => { + switch (sortBy) { + case 'A>Z': + return a.name.toLocaleLowerCase() > b.name.toLocaleLowerCase() ? 1 : -1; + case 'Z>A': + return a.name.toLocaleLowerCase() < b.name.toLocaleLowerCase() ? 1 : -1; + case 'Newest': + if (a.id && b.id) { + return a.id < b.id ? 1 : -1; + } + return -1; + case 'Oldest': + if (a.id && b.id) { + return a.id > b.id ? 1 : -1; + } + return -1; + default: + return 0; + } + }); const { data: backgroundData, isFetching: backgroundDataIsFetching } = useQueryAPI({ endpoint: backgroundsEndpoint, }); @@ -139,6 +161,9 @@ export function Themes() { searchPlaceholder={'Search Themes...'} isLoading={isLoading} setIsLoading={setIsLoading} + sortBy={sortBy} + setSortBy={setSortBy} + customSearchEnabled={false} /> { if (currentThemePlaylist === 'All') { - navigate(`/${import.meta.env.VITE_BASE_URL}/settings/themePlaylists`); + void navigate( + `/${import.meta.env.VITE_BASE_URL}/settings/themePlaylists`, + ); } else { setCurrentThemePlaylist('All'); setCurrentTheme(theme.name); diff --git a/src/pages/settings/components/WoL/WolClients.tsx b/src/pages/settings/components/WoL/WolClients.tsx index f9f3cf1..493b8e8 100644 --- a/src/pages/settings/components/WoL/WolClients.tsx +++ b/src/pages/settings/components/WoL/WolClients.tsx @@ -38,14 +38,40 @@ export function WolClients() { const { data: wolClientsData, isFetching: wolClientsIsFetching } = useQueryAPI({ endpoint: endpoint, }); + const [sortBy, setSortBy] = useState('Oldest'); const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const wolClients: WolClient[] = - wolClientsData.filter( - (a: WolClient) => - a.hostname.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || - a.macAddress.toLowerCase().includes((debouncedSearch as string).toLowerCase()), - ) || []; + wolClientsData + .filter( + (a: WolClient) => + a.hostname.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || + a.macAddress.toLowerCase().includes((debouncedSearch as string).toLowerCase()), + ) + .sort((a: WolClient, b: WolClient) => { + switch (sortBy) { + case 'A>Z': + return a.hostname.toLocaleLowerCase() > b.hostname.toLocaleLowerCase() + ? 1 + : -1; + case 'Z>A': + return a.hostname.toLocaleLowerCase() < b.hostname.toLocaleLowerCase() + ? 1 + : -1; + case 'Newest': + if (a.id && b.id) { + return a.id < b.id ? 1 : -1; + } + return -1; + case 'Oldest': + if (a.id && b.id) { + return a.id > b.id ? 1 : -1; + } + return -1; + default: + return 0; + } + }) || []; const { mutateAsync } = useMutationAPI(); const { isMobile, theme } = useCommonHooks(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); @@ -151,8 +177,9 @@ export function WolClients() { searchPlaceholder={'Search Clients...'} isLoading={isLoading} setIsLoading={setIsLoading} - sortBy={''} - setSortBy={undefined} + sortBy={sortBy} + setSortBy={setSortBy} + customSearchEnabled={false} />