diff --git a/pkg/plugins/app_plugin.go b/pkg/plugins/app_plugin.go index 84b6d6b8111..c1f10201415 100644 --- a/pkg/plugins/app_plugin.go +++ b/pkg/plugins/app_plugin.go @@ -84,6 +84,11 @@ func (app *AppPlugin) InitApp(panels map[string]*PanelPlugin, dataSources map[st cfg *setting.Cfg) []*PluginStaticRoute { staticRoutes := app.InitFrontendPlugin(cfg) + // force enable bundled catalog app + if app.Id == "grafana-plugin-catalog-app" && cfg.CatalogAppEnabled { + app.AutoEnabled = true + } + // check if we have child panels for _, panel := range panels { if strings.HasPrefix(panel.PluginDir, app.PluginDir) { diff --git a/plugins-bundled/internal/plugin-catalog-app/README.md b/plugins-bundled/internal/plugin-catalog-app/README.md index cf1602a5102..b8a4e1f5540 100644 --- a/plugins-bundled/internal/plugin-catalog-app/README.md +++ b/plugins-bundled/internal/plugin-catalog-app/README.md @@ -1,21 +1,5 @@ # Grafana plugin catalog -Browse and manage plugins from within Grafana. +Allow Admin users to browse and manage plugins from within Grafana. -- Admin users can browse plugins, list installed plugins, and install / uninstall plugins - -![Screenshot](/src/img/discover.png) - -## Installation - -1. Navigate to **Configuration** -> **Plugins** and click on the Catalog plugin in the list -1. Click the **Enable app** to enable the plugin -1. Click the **Pin app** to add it to the side menu - -## Configuration - -| Option | Description | -| ------------------------- | ------------------------------------------------ | -| _Enable app_ | Must be done before being able to use the plugin | -| _Pin app_ | Add the app to the side menu | -| _Show Enterprise plugins_ | Show Enterprise plugins in the catalog | +This plugin is **included** with Grafana however it is only accessible if [enabled in Grafana settings](https://grafana.com/docs/grafana/next/administration/configuration/#catalog_app_enabled). diff --git a/plugins-bundled/internal/plugin-catalog-app/src/config/Settings.tsx b/plugins-bundled/internal/plugin-catalog-app/src/config/Settings.tsx deleted file mode 100644 index 575068306d0..00000000000 --- a/plugins-bundled/internal/plugin-catalog-app/src/config/Settings.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useState } from 'react'; -import { PluginConfigPageProps, AppPluginMeta, PluginMeta } from '@grafana/data'; -import { CatalogAppSettings } from 'types'; -import { Button, Field, Legend, Switch } from '@grafana/ui'; -import { api } from '../api'; -import { PLUGIN_ID } from '../constants'; - -interface Props extends PluginConfigPageProps> {} - -export const Settings = ({ plugin }: Props) => { - const [meta, setMeta] = useState(plugin.meta); - const [state, setState] = useState(meta.jsonData ?? {}); - - const { pinned, enabled } = meta; - const { includeEnterprise } = state; - - const onSave = () => { - updateAndReload(PLUGIN_ID, { - pinned, - enabled, - jsonData: state, - }); - }; - - return ( - <> - General - - { - setMeta({ ...meta, enabled: e.currentTarget.checked }); - }} - /> - - - { - setMeta({ ...meta, pinned: e.currentTarget.checked }); - }} - /> - - Plugins - - { - setState({ ...state, includeEnterprise: e.currentTarget.checked }); - }} - /> - - - - ); -}; - -const updateAndReload = async (pluginId: string, data: Partial) => { - try { - await api.updatePlugin(pluginId, data); - - // Reloading the page as the changes made here wouldn't be propagated to the actual plugin otherwise. - // This is not ideal, however unfortunately currently there is no supported way for updating the plugin state. - window.location.reload(); - } catch (e) { - console.error('Error while updating the plugin', e); - } -}; diff --git a/plugins-bundled/internal/plugin-catalog-app/src/hooks/usePlugins.tsx b/plugins-bundled/internal/plugin-catalog-app/src/hooks/usePlugins.tsx index ec96e8ee126..bf1cfa074b0 100644 --- a/plugins-bundled/internal/plugin-catalog-app/src/hooks/usePlugins.tsx +++ b/plugins-bundled/internal/plugin-catalog-app/src/hooks/usePlugins.tsx @@ -9,7 +9,7 @@ type PluginsState = { installedPlugins: any[]; }; -export const usePlugins = (includeEnterprise = false) => { +export const usePlugins = () => { const [state, setState] = useState({ isLoading: true, items: [], installedPlugins: [] }); useEffect(() => { @@ -17,7 +17,7 @@ export const usePlugins = (includeEnterprise = false) => { const items = await api.getRemotePlugins(); const filteredItems = items .filter((plugin) => Boolean(plugin.versionSignatureType)) - .filter((plugin) => includeEnterprise || plugin.status !== 'enterprise') + .filter((plugin) => plugin.status !== 'enterprise') .filter((plugin) => !status || plugin.status === status); const installedPlugins = await api.getInstalledPlugins(); @@ -25,7 +25,7 @@ export const usePlugins = (includeEnterprise = false) => { }; fetchPluginData(); - }, [includeEnterprise]); + }, []); return state; }; diff --git a/plugins-bundled/internal/plugin-catalog-app/src/module.ts b/plugins-bundled/internal/plugin-catalog-app/src/module.ts index 400a4f3ccd8..37605d5484b 100644 --- a/plugins-bundled/internal/plugin-catalog-app/src/module.ts +++ b/plugins-bundled/internal/plugin-catalog-app/src/module.ts @@ -1,15 +1,6 @@ import { ComponentClass } from 'react'; -import { AppPlugin, AppPluginMeta, AppRootProps, PluginConfigPageProps } from '@grafana/data'; -import { Settings } from './config/Settings'; +import { AppPlugin, AppRootProps } from '@grafana/data'; import { MarketplaceRootPage } from './RootPage'; -import { CatalogAppSettings } from './types'; -export const plugin = new AppPlugin() - .setRootPage((MarketplaceRootPage as unknown) as ComponentClass) - .addConfigPage({ - title: 'Settings', - icon: 'info-circle', - body: (Settings as unknown) as ComponentClass>>, - id: 'settings', - }); +export const plugin = new AppPlugin().setRootPage((MarketplaceRootPage as unknown) as ComponentClass); diff --git a/plugins-bundled/internal/plugin-catalog-app/src/pages/Browse.tsx b/plugins-bundled/internal/plugin-catalog-app/src/pages/Browse.tsx index ed592143134..4257e671681 100644 --- a/plugins-bundled/internal/plugin-catalog-app/src/pages/Browse.tsx +++ b/plugins-bundled/internal/plugin-catalog-app/src/pages/Browse.tsx @@ -8,14 +8,13 @@ import { SearchField } from '../components/SearchField'; import { HorizontalGroup } from '../components/HorizontalGroup'; import { usePlugins } from '../hooks/usePlugins'; import { useHistory } from '../hooks/useHistory'; -import { CatalogAppSettings, Plugin } from '../types'; +import { Plugin } from '../types'; import { Page } from 'components/Page'; -export const Browse = ({ query, meta }: AppRootProps) => { +export const Browse = ({ query }: AppRootProps) => { const { q, filterBy, sortBy } = query; - const { includeEnterprise } = meta.jsonData as CatalogAppSettings; - const plugins = usePlugins(includeEnterprise); + const plugins = usePlugins(); const history = useHistory(); const onSortByChange = (value: SelectableValue) => { diff --git a/plugins-bundled/internal/plugin-catalog-app/src/pages/Discover.tsx b/plugins-bundled/internal/plugin-catalog-app/src/pages/Discover.tsx index 6889c9c8f63..b5952306204 100644 --- a/plugins-bundled/internal/plugin-catalog-app/src/pages/Discover.tsx +++ b/plugins-bundled/internal/plugin-catalog-app/src/pages/Discover.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { cx, css } from '@emotion/css'; -import { dateTimeParse, AppRootProps, GrafanaTheme2 } from '@grafana/data'; +import { dateTimeParse, GrafanaTheme2 } from '@grafana/data'; import { useStyles2, Legend, LinkButton } from '@grafana/ui'; import { PLUGIN_ROOT } from '../constants'; @@ -12,14 +12,12 @@ import { SearchField } from '../components/SearchField'; import { PluginTypeIcon } from '../components/PluginTypeIcon'; import { usePlugins } from '../hooks/usePlugins'; import { useHistory } from '../hooks/useHistory'; -import { CatalogAppSettings, Plugin } from '../types'; +import { Plugin } from '../types'; import { Page } from 'components/Page'; import { Loader } from 'components/Loader'; -export const Discover = ({ meta }: AppRootProps) => { - const { includeEnterprise } = meta.jsonData as CatalogAppSettings; - - const { items, isLoading } = usePlugins(includeEnterprise); +export const Discover = () => { + const { items, isLoading } = usePlugins(); const history = useHistory(); const styles = useStyles2(getStyles); diff --git a/plugins-bundled/internal/plugin-catalog-app/src/pages/Library.tsx b/plugins-bundled/internal/plugin-catalog-app/src/pages/Library.tsx index ebf8191fb79..3ed89817bb3 100644 --- a/plugins-bundled/internal/plugin-catalog-app/src/pages/Library.tsx +++ b/plugins-bundled/internal/plugin-catalog-app/src/pages/Library.tsx @@ -9,7 +9,7 @@ import { Page } from 'components/Page'; import { Loader } from 'components/Loader'; export const Library = () => { - const { isLoading, items, installedPlugins } = usePlugins(true); + const { isLoading, items, installedPlugins } = usePlugins(); const styles = useStyles2(getStyles); const filteredPlugins = items.filter((plugin) => !!installedPlugins.find((_) => _.id === plugin.slug)); diff --git a/plugins-bundled/internal/plugin-catalog-app/src/types.ts b/plugins-bundled/internal/plugin-catalog-app/src/types.ts index fea0a2975ff..11e6ab0958a 100644 --- a/plugins-bundled/internal/plugin-catalog-app/src/types.ts +++ b/plugins-bundled/internal/plugin-catalog-app/src/types.ts @@ -1,7 +1,3 @@ -export interface CatalogAppSettings { - includeEnterprise?: boolean; -} - export type PluginTypeCode = 'app' | 'panel' | 'datasource'; export interface Plugin {