mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2026-01-15 16:33:35 -03:00
Add plugin status filter independent of categories
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
/** Options for filtering plugins based on the installation status. */
|
||||
export enum PluginStatusOption {
|
||||
All = 'All',
|
||||
Available = 'Available',
|
||||
Installed = 'Installed'
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import NoPluginResults from 'apps/dashboard/features/plugins/components/NoPlugin
|
||||
import PluginCard from 'apps/dashboard/features/plugins/components/PluginCard';
|
||||
import { CATEGORY_LABELS } from 'apps/dashboard/features/plugins/constants/categoryLabels';
|
||||
import { PluginCategory } from 'apps/dashboard/features/plugins/constants/pluginCategory';
|
||||
import { PluginStatusOption } from 'apps/dashboard/features/plugins/constants/pluginStatusOption';
|
||||
import Loading from 'components/loading/LoadingComponent';
|
||||
import Page from 'components/Page';
|
||||
import globalize from 'lib/globalize';
|
||||
@@ -35,9 +36,6 @@ const MAIN_CATEGORIES = [
|
||||
PluginCategory.Subtitles.toLowerCase()
|
||||
];
|
||||
|
||||
/** The installed meta category. */
|
||||
const INSTALLED_CATEGORY = 'installed';
|
||||
|
||||
export const Component = () => {
|
||||
const {
|
||||
data: pluginDetails,
|
||||
@@ -46,6 +44,7 @@ export const Component = () => {
|
||||
} = usePluginDetails();
|
||||
const [ category, setCategory ] = useState<string>();
|
||||
const [ searchQuery, setSearchQuery ] = useState('');
|
||||
const [ status, setStatus ] = useState<PluginStatusOption>(PluginStatusOption.Installed);
|
||||
|
||||
const onSearchChange = useCallback((event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
|
||||
setSearchQuery(event.target.value);
|
||||
@@ -55,11 +54,14 @@ export const Component = () => {
|
||||
if (pluginDetails) {
|
||||
let filtered = pluginDetails;
|
||||
|
||||
if (status === PluginStatusOption.Installed) {
|
||||
filtered = filtered.filter(p => p.status);
|
||||
} else if (status === PluginStatusOption.Available) {
|
||||
filtered = filtered.filter(p => !p.status);
|
||||
}
|
||||
|
||||
if (category) {
|
||||
if (category === INSTALLED_CATEGORY) {
|
||||
// Installed plugins will have a status
|
||||
filtered = filtered.filter(p => p.status);
|
||||
} else if (category === PluginCategory.Other.toLowerCase()) {
|
||||
if (category === PluginCategory.Other.toLowerCase()) {
|
||||
filtered = filtered.filter(p => (
|
||||
p.category && !MAIN_CATEGORIES.includes(p.category.toLowerCase())
|
||||
));
|
||||
@@ -72,7 +74,7 @@ export const Component = () => {
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}, [ category, pluginDetails, searchQuery ]);
|
||||
}, [ category, pluginDetails, searchQuery, status ]);
|
||||
|
||||
if (isPending) {
|
||||
return <Loading />;
|
||||
@@ -149,6 +151,29 @@ export const Component = () => {
|
||||
overflowX: 'auto'
|
||||
}}
|
||||
>
|
||||
<Chip
|
||||
color={status === PluginStatusOption.All ? 'primary' : undefined}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => setStatus(PluginStatusOption.All)}
|
||||
label={globalize.translate('All')}
|
||||
/>
|
||||
|
||||
<Chip
|
||||
color={status === PluginStatusOption.Available ? 'primary' : undefined}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => setStatus(PluginStatusOption.Available)}
|
||||
label={globalize.translate('LabelAvailable')}
|
||||
/>
|
||||
|
||||
<Chip
|
||||
color={status === PluginStatusOption.Installed ? 'primary' : undefined}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => setStatus(PluginStatusOption.Installed)}
|
||||
label={globalize.translate('LabelInstalled')}
|
||||
/>
|
||||
|
||||
<Divider orientation='vertical' flexItem />
|
||||
|
||||
<Chip
|
||||
color={!category ? 'primary' : undefined}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
@@ -156,15 +181,6 @@ export const Component = () => {
|
||||
label={globalize.translate('All')}
|
||||
/>
|
||||
|
||||
<Chip
|
||||
color={category === INSTALLED_CATEGORY ? 'primary' : undefined}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => setCategory(INSTALLED_CATEGORY)}
|
||||
label={globalize.translate('LabelInstalled')}
|
||||
/>
|
||||
|
||||
<Divider orientation='vertical' flexItem />
|
||||
|
||||
{Object.values(PluginCategory).map(c => (
|
||||
<Chip
|
||||
key={c}
|
||||
@@ -193,7 +209,10 @@ export const Component = () => {
|
||||
<NoPluginResults
|
||||
isFiltered={!!category}
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onViewAll={() => setCategory(undefined)}
|
||||
onViewAll={() => {
|
||||
setCategory(undefined);
|
||||
setStatus(PluginStatusOption.All);
|
||||
}}
|
||||
query={searchQuery}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -626,6 +626,7 @@
|
||||
"LabelAutomaticallyRefreshInternetMetadataEvery": "Automatically refresh metadata from the internet",
|
||||
"LabelAutomaticDiscovery": "Enable Auto Discovery",
|
||||
"LabelAutomaticDiscoveryHelp": "Allow applications to automatically detect Jellyfin by using UDP port 7359.",
|
||||
"LabelAvailable": "Available",
|
||||
"LabelBackupsUnavailable": "No backups available",
|
||||
"LabelBaseUrl": "Base URL",
|
||||
"LabelBaseUrlHelp": "Add a custom subdirectory to the server URL. For example: <code>http://example.com/<b><baseurl></b></code>",
|
||||
|
||||
Reference in New Issue
Block a user