Plugins: Added hook to make it easier to track interactions in plugins (#56126)

* first stab at context away plugin tracking.

* adding a plugin context and a hook to get hold of a tracker that always appends the plugin context information.

* wip

* improved the code a bit.

* wip

* Fixed type errors.

* added datasource_uid to data sources.

* fixed error message when trying to use hook outside of context.

* small refactoring according to feedback.

* using the correct provider for data source context.

* check not needed.

* enforcing the interaction name to start with grafana_plugin_

* exposing guards for the other context type.

* added structure for writing reporter hook tests.

* added some more tests.

* added tests.

* reverted back to inheritance between context types.

* adding mock for getDataSourceSrv
This commit is contained in:
Marcus Andersson
2022-11-02 16:57:57 +01:00
committed by GitHub
parent 932429a545
commit b804b2f073
27 changed files with 591 additions and 104 deletions

View File

@@ -0,0 +1,20 @@
import React, { PropsWithChildren, ReactElement, useMemo } from 'react';
import { DataSourceInstanceSettings } from '../../types';
import { Context, DataSourcePluginContextType } from './PluginContext';
export type DataSourcePluginContextProviderProps = {
instanceSettings: DataSourceInstanceSettings;
};
export function DataSourcePluginContextProvider(
props: PropsWithChildren<DataSourcePluginContextProviderProps>
): ReactElement {
const { children, instanceSettings } = props;
const value: DataSourcePluginContextType = useMemo(() => {
return { instanceSettings, meta: instanceSettings.meta };
}, [instanceSettings]);
return <Context.Provider value={value}>{children}</Context.Provider>;
}

View File

@@ -0,0 +1,14 @@
import { createContext } from 'react';
import { DataSourceInstanceSettings } from '../../types/datasource';
import { PluginMeta } from '../../types/plugin';
export interface PluginContextType {
meta: PluginMeta;
}
export interface DataSourcePluginContextType extends PluginContextType {
instanceSettings: DataSourceInstanceSettings;
}
export const Context = createContext<PluginContextType | undefined>(undefined);

View File

@@ -0,0 +1,14 @@
import React, { PropsWithChildren, ReactElement } from 'react';
import { PluginMeta } from '../../types/plugin';
import { Context } from './PluginContext';
export type PluginContextProviderProps = {
meta: PluginMeta;
};
export function PluginContextProvider(props: PropsWithChildren<PluginContextProviderProps>): ReactElement {
const { children, ...rest } = props;
return <Context.Provider value={rest}>{children}</Context.Provider>;
}

View File

@@ -0,0 +1,5 @@
import { type DataSourcePluginContextType, type PluginContextType } from './PluginContext';
export function isDataSourcePluginContext(context: PluginContextType): context is DataSourcePluginContextType {
return 'instanceSettings' in context && 'meta' in context;
}

View File

@@ -0,0 +1,11 @@
import { useContext } from 'react';
import { Context, PluginContextType } from './PluginContext';
export function usePluginContext(): PluginContextType {
const context = useContext(Context);
if (!context) {
throw new Error('usePluginContext must be used within a PluginContextProvider');
}
return context;
}

View File

@@ -26,4 +26,12 @@ export { PanelPlugin, type SetFieldConfigOptionsArgs, type StandardOptionConfig
export { createFieldConfigRegistry } from './panel/registryFactories';
export { type QueryRunner, type QueryRunnerOptions } from './types/queryRunner';
export { type GroupingToMatrixTransformerOptions } from './transformations/transformers/groupingToMatrix';
export { type PluginContextType, type DataSourcePluginContextType } from './context/plugins/PluginContext';
export { type PluginContextProviderProps, PluginContextProvider } from './context/plugins/PluginContextProvider';
export {
type DataSourcePluginContextProviderProps,
DataSourcePluginContextProvider,
} from './context/plugins/DataSourcePluginContextProvider';
export { usePluginContext } from './context/plugins/usePluginContext';
export { isDataSourcePluginContext } from './context/plugins/guards';
export { getLinksSupplier } from './field/fieldOverrides';