Use query parameters for plugin filters

This commit is contained in:
Bill Thornton
2025-07-30 14:15:18 -04:00
parent 357ce7c9b8
commit 1098ca4447
2 changed files with 24 additions and 10 deletions

View File

@@ -6,7 +6,7 @@ import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import React, { useCallback, useMemo, useState } from 'react';
import React, { useCallback, useMemo } from 'react';
import { Link } from 'react-router-dom';
import SearchInput from 'apps/dashboard/components/SearchInput';
@@ -18,7 +18,9 @@ import { PluginCategory } from 'apps/dashboard/features/plugins/constants/plugin
import { PluginStatusOption } from 'apps/dashboard/features/plugins/constants/pluginStatusOption';
import Loading from 'components/loading/LoadingComponent';
import Page from 'components/Page';
import useSearchParam from 'hooks/useSearchParam';
import globalize from 'lib/globalize';
/**
* The list of primary/main categories.
* Any category not in this list will be added to the "other" category.
@@ -34,23 +36,29 @@ const MAIN_CATEGORIES = [
PluginCategory.Subtitles.toLowerCase()
];
const CATEGORY_PARAM = 'category';
const QUERY_PARAM = 'query';
const STATUS_PARAM = 'status';
export const Component = () => {
const {
data: pluginDetails,
isError,
isPending
} = usePluginDetails();
const [ category, setCategory ] = useState<string>();
const [ searchQuery, setSearchQuery ] = useState('');
const [ status, setStatus ] = useState<PluginStatusOption>(PluginStatusOption.Installed);
const [ category, setCategory ] = useSearchParam(CATEGORY_PARAM);
const [ searchQuery, setSearchQuery ] = useSearchParam(QUERY_PARAM);
const [ status, setStatus ] = useSearchParam(STATUS_PARAM, PluginStatusOption.Installed);
const onSearchChange = useCallback((event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
setSearchQuery(event.target.value);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const onViewAll = useCallback(() => {
if (category) setCategory(undefined);
if (category) setCategory('');
else setStatus(PluginStatusOption.All);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ category ]);
const filteredPlugins = useMemo(() => {
@@ -198,7 +206,7 @@ export const Component = () => {
<Chip
color={!category ? 'primary' : undefined}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => setCategory(undefined)}
onClick={() => setCategory('')}
label={globalize.translate('All')}
/>

View File

@@ -7,15 +7,21 @@ import { usePrevious } from './usePrevious';
* A hook for getting and setting a URL search parameter value that automatically handles updates to/from the URL.
* @param param The search parameter name.
*/
const useSearchParam: (param: string) => [ string, React.Dispatch<React.SetStateAction<string>> ] = param => {
const useSearchParam: (
param: string,
defaultValue?: string
) => [ string, React.Dispatch<React.SetStateAction<string>> ] = (
param,
defaultValue = ''
) => {
const [ searchParams, setSearchParams ] = useSearchParams();
const urlValue = searchParams.get(param) || '';
const urlValue = searchParams.get(param) || defaultValue;
const [ value, setValue ] = useState(urlValue);
const previousValue = usePrevious(value, '');
const previousValue = usePrevious(value, defaultValue);
useEffect(() => {
if (value !== previousValue) {
if (value === '' && urlValue !== '') {
if (value === defaultValue && urlValue !== defaultValue) {
// The query input has been cleared; remove the url param
searchParams.delete(param);
setSearchParams(searchParams, { replace: true });