|
|
|
@ -1,7 +1,7 @@ |
|
|
|
|
import { useMemo } from 'react'; |
|
|
|
|
import { useObservable } from 'react-use'; |
|
|
|
|
|
|
|
|
|
import { usePluginContext } from '@grafana/data'; |
|
|
|
|
import { PluginExtensionComponentMeta, PluginExtensionTypes, usePluginContext } from '@grafana/data'; |
|
|
|
|
import { |
|
|
|
|
UsePluginComponentOptions, |
|
|
|
|
UsePluginComponentsResult, |
|
|
|
@ -10,8 +10,9 @@ import { |
|
|
|
|
import { useAddedComponentsRegistry } from './ExtensionRegistriesContext'; |
|
|
|
|
import * as errors from './errors'; |
|
|
|
|
import { log } from './logs/log'; |
|
|
|
|
import { AddedComponentRegistryItem } from './registry/AddedComponentsRegistry'; |
|
|
|
|
import { useLoadAppPlugins } from './useLoadAppPlugins'; |
|
|
|
|
import { getExtensionPointPluginDependencies, isGrafanaDevMode } from './utils'; |
|
|
|
|
import { generateExtensionId, getExtensionPointPluginDependencies, isGrafanaDevMode } from './utils'; |
|
|
|
|
import { isExtensionPointIdValid, isExtensionPointMetaInfoMissing } from './validators'; |
|
|
|
|
|
|
|
|
|
// Returns an array of component extensions for the given extension point
|
|
|
|
@ -27,7 +28,7 @@ export function usePluginComponents<Props extends object = {}>({ |
|
|
|
|
return useMemo(() => { |
|
|
|
|
// For backwards compatibility we don't enable restrictions in production or when the hook is used in core Grafana.
|
|
|
|
|
const enableRestrictions = isGrafanaDevMode() && pluginContext; |
|
|
|
|
const components: Array<React.ComponentType<Props>> = []; |
|
|
|
|
const components: Array<React.ComponentType<Props> & { meta: PluginExtensionComponentMeta }> = []; |
|
|
|
|
const extensionsByPlugin: Record<string, number> = {}; |
|
|
|
|
const pluginId = pluginContext?.meta.id ?? ''; |
|
|
|
|
const pointLog = log.child({ |
|
|
|
@ -66,7 +67,12 @@ export function usePluginComponents<Props extends object = {}>({ |
|
|
|
|
extensionsByPlugin[pluginId] = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
components.push(registryItem.component as React.ComponentType<Props>); |
|
|
|
|
const component = createComponentWithMeta<Props>( |
|
|
|
|
registryItem as AddedComponentRegistryItem<Props>, |
|
|
|
|
extensionPointId |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
components.push(component); |
|
|
|
|
extensionsByPlugin[pluginId] += 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -76,3 +82,27 @@ export function usePluginComponents<Props extends object = {}>({ |
|
|
|
|
}; |
|
|
|
|
}, [extensionPointId, limitPerPlugin, pluginContext, registryState, isLoadingAppPlugins]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function createComponentWithMeta<Props extends JSX.IntrinsicAttributes>( |
|
|
|
|
registryItem: AddedComponentRegistryItem<Props>, |
|
|
|
|
extensionPointId: string |
|
|
|
|
): React.ComponentType<Props> & { meta: PluginExtensionComponentMeta } { |
|
|
|
|
const { component: Component, ...config } = registryItem; |
|
|
|
|
function ComponentWithMeta(props: Props) { |
|
|
|
|
return <Component {...props} />; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ComponentWithMeta.displayName = Component.displayName; |
|
|
|
|
ComponentWithMeta.defaultProps = Component.defaultProps; |
|
|
|
|
ComponentWithMeta.propTypes = Component.propTypes; |
|
|
|
|
ComponentWithMeta.contextTypes = Component.contextTypes; |
|
|
|
|
ComponentWithMeta.meta = { |
|
|
|
|
pluginId: config.pluginId, |
|
|
|
|
title: config.title ?? '', |
|
|
|
|
description: config.description ?? '', |
|
|
|
|
id: generateExtensionId(config.pluginId, extensionPointId, config.title), |
|
|
|
|
type: PluginExtensionTypes.component, |
|
|
|
|
} satisfies PluginExtensionComponentMeta; |
|
|
|
|
|
|
|
|
|
return ComponentWithMeta; |
|
|
|
|
} |
|
|
|
|