PluginExtensions: Start using new APIs for datasource config extensions point (#101139)

pull/101136/head^2
Marcus Andersson 5 months ago committed by GitHub
parent eca045bc11
commit 7773c658bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 73
      public/app/features/datasources/components/EditDataSource.test.tsx
  2. 46
      public/app/features/datasources/components/EditDataSource.tsx
  3. 3
      public/app/features/plugins/extensions/usePluginComponents.tsx

@ -1,8 +1,9 @@
import { screen, render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { PluginExtensionTypes, PluginState } from '@grafana/data';
import { setAngularLoader, setPluginExtensionsHook } from '@grafana/runtime';
import { PluginState } from '@grafana/data';
import { setAngularLoader, setPluginComponentsHook } from '@grafana/runtime';
import { createComponentWithMeta } from 'app/features/plugins/extensions/usePluginComponents';
import { configureStore } from 'app/store/configureStore';
import { getMockDataSource, getMockDataSourceMeta, getMockDataSourceSettingsState } from '../__mocks__';
@ -58,7 +59,7 @@ describe('<EditDataSource>', () => {
});
beforeEach(() => {
setPluginExtensionsHook(jest.fn().mockReturnValue({ extensions: [] }));
setPluginComponentsHook(jest.fn().mockReturnValue({ isLoading: false, components: [] }));
});
describe('On loading errors', () => {
@ -268,17 +269,19 @@ describe('<EditDataSource>', () => {
it('should be possible to extend the form with a "component" extension in case the plugin ID is whitelisted', () => {
const message = "I'm a UI extension component!";
setPluginExtensionsHook(
setPluginComponentsHook(
jest.fn().mockReturnValue({
extensions: [
{
id: '1',
pluginId: 'grafana-pdc-app',
type: PluginExtensionTypes.component,
title: 'Example component',
description: 'Example description',
component: () => <div>{message}</div>,
},
isLoading: false,
components: [
createComponentWithMeta(
{
pluginId: 'grafana-pdc-app',
title: 'Example component',
description: 'Example description',
component: () => <div>{message}</div>,
},
'1'
),
],
})
);
@ -297,17 +300,19 @@ describe('<EditDataSource>', () => {
it('should NOT be possible to extend the form with a "component" extension in case the plugin ID is NOT whitelisted', () => {
const message = "I'm a UI extension component!";
setPluginExtensionsHook(
setPluginComponentsHook(
jest.fn().mockReturnValue({
extensions: [
{
id: '1',
pluginId: 'myorg-basic-app',
type: PluginExtensionTypes.component,
title: 'Example component',
description: 'Example description',
component: () => <div>{message}</div>,
},
isLoading: false,
components: [
createComponentWithMeta(
{
pluginId: 'myorg-basic-app',
title: 'Example component',
description: 'Example description',
component: () => <div>{message}</div>,
},
'1'
),
],
})
);
@ -327,17 +332,19 @@ describe('<EditDataSource>', () => {
const message = "I'm a UI extension component!";
const component = jest.fn().mockReturnValue(<div>{message}</div>);
setPluginExtensionsHook(
setPluginComponentsHook(
jest.fn().mockReturnValue({
extensions: [
{
id: '1',
pluginId: 'grafana-pdc-app',
type: PluginExtensionTypes.component,
title: 'Example component',
description: 'Example description',
component,
},
isLoading: false,
components: [
createComponentWithMeta(
{
pluginId: 'grafana-pdc-app',
title: 'Example component',
description: 'Example description',
component,
},
'1'
),
],
})
);

@ -9,10 +9,9 @@ import {
DataSourceSettings as DataSourceSettingsType,
PluginExtensionPoints,
PluginExtensionDataSourceConfigContext,
DataSourceJsonData,
DataSourceUpdatedSuccessfully,
} from '@grafana/data';
import { getDataSourceSrv, usePluginComponentExtensions } from '@grafana/runtime';
import { getDataSourceSrv, usePluginComponents, UsePluginComponentsResult } from '@grafana/runtime';
import appEvents from 'app/core/app_events';
import PageLoader from 'app/core/components/PageLoader/PageLoader';
import { DataSourceSettingsState, useDispatch } from 'app/types';
@ -118,6 +117,7 @@ export function EditDataSourceView({
const { plugin, loadError, testingStatus, loading } = dataSourceSettings;
const { readOnly, hasWriteRights, hasDeleteRights } = dataSourceRights;
const hasDataSource = dataSource.id > 0;
const { components, isLoading } = useDataSourceConfigPluginExtensions();
const dsi = getDataSourceSrv()?.getInstanceSettings(dataSource.uid);
@ -137,16 +137,6 @@ export function EditDataSourceView({
onTest();
};
const extensionPointId = PluginExtensionPoints.DataSourceConfig;
const { extensions } = usePluginComponentExtensions<{
context: PluginExtensionDataSourceConfigContext<DataSourceJsonData>;
}>({ extensionPointId });
const allowedExtensions = useMemo(() => {
const allowedPluginIds = ['grafana-pdc-app', 'grafana-auth-app'];
return extensions.filter((e) => allowedPluginIds.includes(e.pluginId));
}, [extensions]);
if (loadError) {
return (
<DataSourceLoadError
@ -159,7 +149,7 @@ export function EditDataSourceView({
);
}
if (loading) {
if (loading || isLoading) {
return <PageLoader />;
}
@ -204,11 +194,9 @@ export function EditDataSourceView({
)}
{/* Extension point */}
{allowedExtensions.map((extension) => {
const Component = extension.component;
{components.map((Component) => {
return (
<div key={extension.id}>
<div key={Component.meta.id}>
<Component
context={{
dataSource: cloneDeep(dataSource),
@ -248,3 +236,27 @@ export function EditDataSourceView({
</form>
);
}
type DataSourceConfigPluginExtensionProps = {
context: PluginExtensionDataSourceConfigContext;
};
function useDataSourceConfigPluginExtensions(): UsePluginComponentsResult<DataSourceConfigPluginExtensionProps> {
const { components, isLoading } = usePluginComponents<DataSourceConfigPluginExtensionProps>({
extensionPointId: PluginExtensionPoints.DataSourceConfig,
});
return useMemo(() => {
const allowedComponents = components.filter((component) => {
switch (component.meta.pluginId) {
case 'grafana-pdc-app':
case 'grafana-auth-app':
return true;
default:
return false;
}
});
return { components: allowedComponents, isLoading };
}, [components, isLoading]);
}

@ -80,7 +80,8 @@ export function usePluginComponents<Props extends object = {}>({
}, [extensionPointId, limitPerPlugin, pluginContext, registryState, isLoadingAppPlugins]);
}
function createComponentWithMeta<Props extends JSX.IntrinsicAttributes>(
// exported so it can be used in tests
export function createComponentWithMeta<Props extends JSX.IntrinsicAttributes>(
registryItem: AddedComponentRegistryItem<Props>,
extensionPointId: string
): React.ComponentType<Props> & { meta: PluginExtensionComponentMeta } {

Loading…
Cancel
Save