diff --git a/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx b/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx
index ffcb3059789..6a045fca1a4 100644
--- a/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx
+++ b/public/app/features/plugins/admin/hooks/usePluginDetailsTabs.tsx
@@ -9,15 +9,18 @@ type ReturnType = {
error: Error | undefined;
loading: boolean;
tabs: PluginDetailsTab[];
+ defaultTab: string;
};
export const usePluginDetailsTabs = (plugin?: CatalogPlugin, defaultTabs: PluginDetailsTab[] = []): ReturnType => {
const { loading, error, value: pluginConfig } = usePluginConfig(plugin);
const isPublished = Boolean(plugin?.isPublished);
const { pathname } = useLocation();
- const tabs = useMemo(() => {
+
+ const [tabs, defaultTab] = useMemo(() => {
const canConfigurePlugins = isOrgAdmin();
const tabs: PluginDetailsTab[] = [...defaultTabs];
+ let defaultTab;
if (isPublished) {
tabs.push({
@@ -30,7 +33,8 @@ export const usePluginDetailsTabs = (plugin?: CatalogPlugin, defaultTabs: Plugin
// Not extending the tabs with the config pages if the plugin is not installed
if (!pluginConfig) {
- return tabs;
+ defaultTab = PluginTabIds.OVERVIEW;
+ return [tabs, defaultTab];
}
if (canConfigurePlugins) {
@@ -42,6 +46,7 @@ export const usePluginDetailsTabs = (plugin?: CatalogPlugin, defaultTabs: Plugin
id: PluginTabIds.CONFIG,
href: `${pathname}?page=${PluginTabIds.CONFIG}`,
});
+ defaultTab = PluginTabIds.CONFIG;
}
if (pluginConfig.configPages) {
@@ -52,6 +57,9 @@ export const usePluginDetailsTabs = (plugin?: CatalogPlugin, defaultTabs: Plugin
id: page.id,
href: `${pathname}?page=${page.id}`,
});
+ if (!defaultTab) {
+ defaultTab = page.id;
+ }
}
}
@@ -66,12 +74,17 @@ export const usePluginDetailsTabs = (plugin?: CatalogPlugin, defaultTabs: Plugin
}
}
- return tabs;
+ if (!defaultTab) {
+ defaultTab = PluginTabIds.OVERVIEW;
+ }
+
+ return [tabs, defaultTab];
}, [pluginConfig, defaultTabs, pathname, isPublished]);
return {
error,
loading,
tabs,
+ defaultTab,
};
};
diff --git a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx
index b199ad581cf..6e6ba894a97 100644
--- a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx
+++ b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx
@@ -40,7 +40,7 @@ jest.mock('../hooks/usePluginConfig.tsx', () => ({
const renderPluginDetails = (
pluginOverride: Partial
,
{
- pageId = PluginTabIds.OVERVIEW,
+ pageId,
pluginsStateOverride,
}: {
pageId?: PluginTabIds;
@@ -55,7 +55,7 @@ const renderPluginDetails = (
location: {
hash: '',
pathname: `/plugins/${id}`,
- search: `?page=${pageId}`,
+ search: pageId ? `?page=${pageId}` : '',
state: undefined,
},
});
@@ -118,11 +118,11 @@ describe('Plugin details page', () => {
const props = getRouteComponentProps({
match: { params: { pluginId: id }, isExact: true, url: '', path: '' },
- queryParams: { page: PluginTabIds.OVERVIEW },
+ queryParams: {},
location: {
hash: '',
pathname: `/plugins/${id}`,
- search: `?page=${PluginTabIds.OVERVIEW}`,
+ search: '',
state: undefined,
},
});
@@ -145,6 +145,40 @@ describe('Plugin details page', () => {
await waitFor(() => expect(queryByText(/licensed under the apache 2.0 license/i)).toBeInTheDocument());
});
+ it('should display an app config page by default for installed app plugins', async () => {
+ const name = 'Akumuli';
+
+ // @ts-ignore
+ usePluginConfig.mockReturnValue({
+ value: {
+ meta: {
+ type: PluginType.app,
+ enabled: false,
+ pinned: false,
+ jsonData: {},
+ },
+ configPages: [
+ {
+ title: 'Config',
+ icon: 'cog',
+ id: 'configPage',
+ body: function ConfigPage() {
+ return Custom Config Page!
;
+ },
+ },
+ ],
+ },
+ });
+
+ const { queryByText } = renderPluginDetails({
+ name,
+ isInstalled: true,
+ type: PluginType.app,
+ });
+
+ await waitFor(() => expect(queryByText(/custom config page/i)).toBeInTheDocument());
+ });
+
it('should display the number of downloads in the header', async () => {
// depending on what locale you have the Intl.NumberFormat will return a format that contains
// whitespaces. In that case we don't want testing library to remove whitespaces.
diff --git a/public/app/features/plugins/admin/pages/PluginDetails.tsx b/public/app/features/plugins/admin/pages/PluginDetails.tsx
index e8bd18aee35..8674ca21f0d 100644
--- a/public/app/features/plugins/admin/pages/PluginDetails.tsx
+++ b/public/app/features/plugins/admin/pages/PluginDetails.tsx
@@ -25,7 +25,6 @@ export default function PluginDetails({ match, queryParams }: Props): JSX.Elemen
params: { pluginId = '' },
url,
} = match;
- const pageId = (queryParams.page as PluginTabIds) || PluginTabIds.OVERVIEW;
const parentUrl = url.substring(0, url.lastIndexOf('/'));
const defaultTabs: PluginDetailsTab[] = [
{
@@ -36,11 +35,12 @@ export default function PluginDetails({ match, queryParams }: Props): JSX.Elemen
},
];
const plugin = useGetSingle(pluginId); // fetches the localplugin settings
- const { tabs } = usePluginDetailsTabs(plugin, defaultTabs);
+ const { tabs, defaultTab } = usePluginDetailsTabs(plugin, defaultTabs);
const { isLoading: isFetchLoading } = useFetchStatus();
const { isLoading: isFetchDetailsLoading } = useFetchDetailsStatus();
const styles = useStyles2(getStyles);
const prevTabs = usePrevious(tabs);
+ const pageId = (queryParams.page as PluginTabIds) || defaultTab;
// If an app plugin is uninstalled we need to reset the active tab when the config / dashboards tabs are removed.
useEffect(() => {
@@ -95,7 +95,7 @@ export default function PluginDetails({ match, queryParams }: Props): JSX.Elemen
-
+