mirror of
https://github.com/grafana/grafana.git
synced 2025-02-15 10:03:33 -06:00
* Explore: Allow the use of plugin panels Allow plugins to define a visualisation to use in explore that comes from a plugin. * Explore: Allow the use of plugin panels Rename ExplorePanel to CustomContainer * Explore: Allow the use of plugin panels Changed CustomContainer to take all frames for plugin id. Add field preferredVisualisationPluginId to frame metadata. Updated decorators to check for plugin and fallback to preferredVisualisationType if plugin cannot be found. * Explore: Allow the use of plugin panels Handle case where there are no custom frames * Explore: Allow the use of plugin panels Add test cases
75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { PanelPlugin, PanelPluginMeta } from '@grafana/data';
|
|
import config from 'app/core/config';
|
|
|
|
import { getPanelPluginLoadError } from '../panel/components/PanelPluginError';
|
|
|
|
import { importPluginModule } from './plugin_loader';
|
|
|
|
const promiseCache: Record<string, Promise<PanelPlugin>> = {};
|
|
const panelPluginCache: Record<string, PanelPlugin> = {};
|
|
|
|
export function importPanelPlugin(id: string): Promise<PanelPlugin> {
|
|
const loaded = promiseCache[id];
|
|
if (loaded) {
|
|
return loaded;
|
|
}
|
|
|
|
const meta = getPanelPluginMeta(id);
|
|
|
|
if (!meta) {
|
|
throw new Error(`Plugin ${id} not found`);
|
|
}
|
|
|
|
promiseCache[id] = getPanelPlugin(meta);
|
|
if (id !== meta.type) {
|
|
promiseCache[meta.type] = promiseCache[id];
|
|
}
|
|
|
|
return promiseCache[id];
|
|
}
|
|
|
|
export function hasPanelPlugin(id: string): boolean {
|
|
return !!getPanelPluginMeta(id);
|
|
}
|
|
|
|
export function getPanelPluginMeta(id: string): PanelPluginMeta {
|
|
return config.panels[id] || Object.values(config.panels).find((p) => p.alias === id);
|
|
}
|
|
|
|
export function importPanelPluginFromMeta(meta: PanelPluginMeta): Promise<PanelPlugin> {
|
|
return getPanelPlugin(meta);
|
|
}
|
|
|
|
export function syncGetPanelPlugin(id: string): PanelPlugin | undefined {
|
|
return panelPluginCache[id];
|
|
}
|
|
|
|
function getPanelPlugin(meta: PanelPluginMeta): Promise<PanelPlugin> {
|
|
return importPluginModule({
|
|
path: meta.module,
|
|
version: meta.info?.version,
|
|
isAngular: meta.angularDetected,
|
|
pluginId: meta.id,
|
|
})
|
|
.then((pluginExports) => {
|
|
if (pluginExports.plugin) {
|
|
return pluginExports.plugin as PanelPlugin;
|
|
} else if (pluginExports.PanelCtrl) {
|
|
const plugin = new PanelPlugin(null);
|
|
plugin.angularPanelCtrl = pluginExports.PanelCtrl;
|
|
return plugin;
|
|
}
|
|
throw new Error('missing export: plugin or PanelCtrl');
|
|
})
|
|
.then((plugin) => {
|
|
plugin.meta = meta;
|
|
panelPluginCache[meta.id] = plugin;
|
|
return plugin;
|
|
})
|
|
.catch((err) => {
|
|
// TODO, maybe a different error plugin
|
|
console.warn('Error loading panel plugin: ' + meta.id, err);
|
|
return getPanelPluginLoadError(meta, err);
|
|
});
|
|
}
|