PluginDrawer now fetches plugin details itself. (#12703)

This commit is contained in:
James Todd
2026-08-25 09:00:39 +10:00
committed by GitHub
parent 176ef1af81
commit 0ff2f7f3cb
2 changed files with 49 additions and 30 deletions
@@ -1,7 +1,7 @@
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
import { Accordion, Alert, Card, Stack, Text } from '@mantine/core'; import { Accordion, Alert, Card, Stack, Text } from '@mantine/core';
import { IconExclamationCircle } from '@tabler/icons-react'; import { IconExclamationCircle } from '@tabler/icons-react';
import { useMemo } from 'react'; import { useEffect, useMemo } from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { StylishText } from '@lib/components/StylishText'; import { StylishText } from '@lib/components/StylishText';
@@ -17,10 +17,10 @@ import PluginSettingsPanel from './PluginSettingsPanel';
*/ */
export default function PluginDrawer({ export default function PluginDrawer({
pluginKey, pluginKey,
pluginInstance onPluginLoaded
}: Readonly<{ }: Readonly<{
pluginKey?: string; pluginKey: string;
pluginInstance: PluginInterface; onPluginLoaded?: (plugin: PluginInterface) => void;
}>) { }>) {
const { id } = useParams(); const { id } = useParams();
@@ -28,6 +28,15 @@ export default function PluginDrawer({
return pluginKey || id || ''; return pluginKey || id || '';
}, [pluginKey, id]); }, [pluginKey, id]);
const {
instance: plugin,
instanceQuery: { isFetching, error }
} = useInstance<PluginInterface>({
endpoint: ApiEndpoints.plugin_list,
hasPrimaryKey: true,
pk: pluginPrimaryKey
});
const { instance: pluginAdmin } = useInstance({ const { instance: pluginAdmin } = useInstance({
endpoint: ApiEndpoints.plugin_admin, endpoint: ApiEndpoints.plugin_admin,
pathParams: { key: pluginPrimaryKey }, pathParams: { key: pluginPrimaryKey },
@@ -36,11 +45,21 @@ export default function PluginDrawer({
refetchOnMount: true refetchOnMount: true
}); });
const hasSettings: boolean = useMemo(() => { useEffect(() => {
return !!pluginInstance?.mixins?.settings; if (plugin) {
}, [pluginInstance]); onPluginLoaded?.(plugin);
}
}, [plugin, onPluginLoaded]);
if (!pluginInstance.active) { const hasSettings: boolean = useMemo(() => {
return !!plugin?.mixins?.settings;
}, [plugin]);
if (isFetching || !plugin) {
return null;
}
if (!plugin.active) {
return ( return (
<Alert <Alert
color='red' color='red'
@@ -63,42 +82,38 @@ export default function PluginDrawer({
<Card withBorder> <Card withBorder>
<Stack gap='md'> <Stack gap='md'>
<Stack pos='relative' gap='xs'> <Stack pos='relative' gap='xs'>
<InfoItem <InfoItem type='text' name={t`Name`} value={plugin?.name} />
type='text'
name={t`Name`}
value={pluginInstance?.name}
/>
<InfoItem <InfoItem
type='text' type='text'
name={t`Description`} name={t`Description`}
value={pluginInstance?.meta.description} value={plugin?.meta.description}
/> />
<InfoItem <InfoItem
type='text' type='text'
name={t`Author`} name={t`Author`}
value={pluginInstance?.meta.author} value={plugin?.meta.author}
/> />
<InfoItem <InfoItem
type='text' type='text'
name={t`Date`} name={t`Date`}
value={pluginInstance?.meta.pub_date} value={plugin?.meta.pub_date}
/> />
<InfoItem <InfoItem
type='text' type='text'
name={t`Version`} name={t`Version`}
value={pluginInstance?.meta.version} value={plugin?.meta.version}
/> />
<InfoItem <InfoItem
type='boolean' type='boolean'
name={t`Active`} name={t`Active`}
value={pluginInstance?.active} value={plugin?.active}
/> />
{pluginInstance?.meta.website && ( {plugin?.meta.website && (
<InfoItem <InfoItem
type='text' type='text'
name={t`Website`} name={t`Website`}
value={pluginInstance?.meta.website} value={plugin?.meta.website}
link={pluginInstance?.meta.website} link={plugin?.meta.website}
/> />
)} )}
</Stack> </Stack>
@@ -107,27 +122,27 @@ export default function PluginDrawer({
<Card withBorder> <Card withBorder>
<Stack gap='md'> <Stack gap='md'>
<Stack pos='relative' gap='xs'> <Stack pos='relative' gap='xs'>
{pluginInstance?.is_package && ( {plugin?.is_package && (
<InfoItem <InfoItem
type='text' type='text'
name={t`Package Name`} name={t`Package Name`}
value={pluginInstance?.package_name} value={plugin?.package_name}
/> />
)} )}
<InfoItem <InfoItem
type='text' type='text'
name={t`Installation Path`} name={t`Installation Path`}
value={pluginInstance?.meta.package_path} value={plugin?.meta.package_path}
/> />
<InfoItem <InfoItem
type='boolean' type='boolean'
name={t`Builtin`} name={t`Builtin`}
value={pluginInstance?.is_builtin} value={plugin?.is_builtin}
/> />
<InfoItem <InfoItem
type='boolean' type='boolean'
name={t`Package`} name={t`Package`}
value={pluginInstance?.is_package} value={plugin?.is_package}
/> />
</Stack> </Stack>
</Stack> </Stack>
@@ -151,7 +151,6 @@ export default function PluginListTable() {
]; ];
}, []); }, []);
const [selectedPlugin, setSelectedPlugin] = useState<any>({});
const [selectedPluginKey, setSelectedPluginKey] = useState<string>(''); const [selectedPluginKey, setSelectedPluginKey] = useState<string>('');
const [activate, setActivate] = useState<boolean>(false); const [activate, setActivate] = useState<boolean>(false);
@@ -266,6 +265,7 @@ export default function PluginListTable() {
); );
const [pluginPackage, setPluginPackage] = useState<string>(''); const [pluginPackage, setPluginPackage] = useState<string>('');
const [pluginName, setPluginName] = useState('');
const activatePluginModal = useEditApiFormModal({ const activatePluginModal = useEditApiFormModal({
title: activate ? t`Activate Plugin` : t`Deactivate Plugin`, title: activate ? t`Activate Plugin` : t`Deactivate Plugin`,
@@ -358,6 +358,10 @@ export default function PluginListTable() {
}); });
}, []); }, []);
const handlePluginLoaded = useCallback((plugin: PluginInterface) => {
setPluginName(plugin.name);
}, []);
// Custom table actions // Custom table actions
const tableActions = useMemo(() => { const tableActions = useMemo(() => {
if ( if (
@@ -397,14 +401,15 @@ export default function PluginListTable() {
{deletePluginModal.modal} {deletePluginModal.modal}
{activatePluginModal.modal} {activatePluginModal.modal}
<DetailDrawer <DetailDrawer
title={`${t`Plugin Detail`} - ${selectedPlugin?.name}`} title={`${t`Plugin Detail`} - ${pluginName}`}
size={'65%'} size={'65%'}
renderContent={(pluginKey) => { renderContent={(pluginKey) => {
if (!pluginKey) return; if (!pluginKey) return;
return ( return (
<PluginDrawer <PluginDrawer
pluginKey={pluginKey} pluginKey={pluginKey}
pluginInstance={selectedPlugin} onPluginLoaded={handlePluginLoaded}
/> />
); );
}} }}
@@ -417,7 +422,6 @@ export default function PluginListTable() {
enableDownload: false, enableDownload: false,
rowActions: rowActions, rowActions: rowActions,
onRowClick: (plugin) => { onRowClick: (plugin) => {
setSelectedPlugin(plugin);
navigate(`${plugin.key}/`); navigate(`${plugin.key}/`);
}, },
tableActions: tableActions, tableActions: tableActions,