2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

Add loading indicator for custom panels (#9194)

This commit is contained in:
Oliver 2025-02-27 15:25:56 +11:00 committed by GitHub
parent 92edbf41ab
commit 28259a1ad6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 23 deletions

View File

@ -1,6 +1,8 @@
import {
ActionIcon,
Divider,
Group,
Loader,
Paper,
Stack,
Tabs,
@ -78,7 +80,7 @@ function BasePanelGroup({
const [expanded, setExpanded] = useState<boolean>(true);
// Hook to load plugins for this panel
const pluginPanels = usePluginPanels({
const pluginPanelSet = usePluginPanels({
model: model,
instance: instance,
id: id
@ -89,7 +91,7 @@ function BasePanelGroup({
const _panels = [...panels];
// Add plugin panels
pluginPanels?.forEach((panel) => {
pluginPanelSet.panels?.forEach((panel) => {
let panelKey = panel.name;
// Check if panel with this name already exists
@ -107,7 +109,7 @@ function BasePanelGroup({
});
return _panels;
}, [panels, pluginPanels]);
}, [panels, pluginPanelSet]);
const activePanels = useMemo(
() => allPanels.filter((panel) => !panel.hidden && !panel.disabled),
@ -188,20 +190,23 @@ function BasePanelGroup({
)
)}
{collapsible && (
<ActionIcon
style={{
paddingLeft: '10px'
}}
onClick={() => setExpanded(!expanded)}
variant='transparent'
size='md'
>
{expanded ? (
<IconLayoutSidebarLeftCollapse opacity={0.5} />
) : (
<IconLayoutSidebarRightCollapse opacity={0.5} />
)}
</ActionIcon>
<Group wrap='nowrap' gap='xs'>
<ActionIcon
style={{
paddingLeft: '10px'
}}
onClick={() => setExpanded(!expanded)}
variant='transparent'
size='md'
>
{expanded ? (
<IconLayoutSidebarLeftCollapse opacity={0.5} />
) : (
<IconLayoutSidebarRightCollapse opacity={0.5} />
)}
</ActionIcon>
{pluginPanelSet.isLoading && <Loader size='xs' />}
</Group>
)}
</Tabs.List>
{allPanels.map(

View File

@ -1,4 +1,4 @@
import { useQuery } from '@tanstack/react-query';
import { type UseQueryResult, useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import { api } from '../App';
@ -35,6 +35,13 @@ export type PluginPanelContext = InvenTreeContext & {
*/
export type PluginPanelType = PanelType & {
pluginName: string;
isLoading: boolean;
};
export type PluginPanelSet = {
panels: PluginPanelType[];
query: UseQueryResult;
isLoading: boolean;
};
export function usePluginPanels({
@ -45,7 +52,7 @@ export function usePluginPanels({
instance?: any;
model?: ModelType | string;
id?: string | number | null;
}): PluginPanelType[] {
}): PluginPanelSet {
const globalSettings = useGlobalSettingsState();
const pluginPanelsEnabled: boolean = useMemo(
@ -54,7 +61,7 @@ export function usePluginPanels({
);
// API query to fetch initial information on available plugin panels
const { data: pluginData } = useQuery({
const pluginQuery = useQuery({
enabled: pluginPanelsEnabled && !!model && id !== undefined,
queryKey: ['custom-plugin-panels', model, id],
queryFn: async () => {
@ -95,7 +102,7 @@ export function usePluginPanels({
const pluginPanels: PluginPanelType[] = useMemo(() => {
return (
pluginData?.map((props: PluginUIFeature) => {
pluginQuery?.data?.map((props: PluginUIFeature) => {
const iconName: string = props?.icon || 'ti:plug:outline';
const pluginContext: any = {
@ -117,7 +124,15 @@ export function usePluginPanels({
};
}) ?? []
);
}, [pluginData, contextData]);
}, [pluginQuery.data, contextData]);
return pluginPanels;
const panelSet: PluginPanelSet = useMemo(() => {
return {
panels: pluginPanels,
isLoading: pluginQuery.isLoading || pluginQuery.isFetching,
query: pluginQuery
};
}, [pluginPanels, pluginQuery]);
return panelSet;
}