The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/features/plugins/extensions/usePluginLinks.tsx

87 lines
2.9 KiB

Plugin extensions: Introduce new registry for added links (#92343) * add added component registry * fix broken test * add tests for usePluginComponents hook * readd expose components * add type assertion exceptions to betterer results * use new addedComponent registry in legacy endpoints * remove unused code * cleanup * revert test code * remove commented code * initial commit * refactor sync method and hook * fix tests * subscribe to the correct registry * remove old registry * cleanup types * add use usePluginLinks hook * add more tests * fix import order * fix typo * fix and temporarly skip failing tests * wip * add hook tests * add more tests * remove old hook * fix versioning * add version to all extension point ids * remove cleanup * remove unused imports * revert touched file * fix test * test: remove hook creation * catch init error * send error to faro * fix broken hook * comment out call hook initialization * use the right import ofr isString * remove unused import * remove registryState type * pr feedback * Update public/app/features/plugins/extensions/validators.test.tsx Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> * Update public/app/features/plugins/extensions/validators.test.tsx Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> * remove no longer relevant comment * fix broken tests * Fixed test to verify that the memotization works properly. * simplify hooks --------- Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
9 months ago
import { isString } from 'lodash';
import { useMemo } from 'react';
import { useObservable } from 'react-use';
import { PluginExtensionLink, PluginExtensionTypes } from '@grafana/data';
import {
UsePluginLinksOptions,
UsePluginLinksResult,
} from '@grafana/runtime/src/services/pluginExtensions/getPluginExtensions';
import { AddedLinksRegistry } from './registry/AddedLinksRegistry';
import {
generateExtensionId,
getLinkExtensionOnClick,
getLinkExtensionOverrides,
getLinkExtensionPathWithTracking,
getReadOnlyProxy,
} from './utils';
// Returns an array of component extensions for the given extension point
export function createUsePluginLinks(registry: AddedLinksRegistry) {
const observableRegistry = registry.asObservable();
return function usePluginLinks({
limitPerPlugin,
extensionPointId,
context,
}: UsePluginLinksOptions): UsePluginLinksResult {
const registry = useObservable(observableRegistry);
return useMemo(() => {
if (!registry || !registry[extensionPointId]) {
return {
isLoading: false,
links: [],
};
}
const frozenContext = context ? getReadOnlyProxy(context) : {};
const extensions: PluginExtensionLink[] = [];
const extensionsByPlugin: Record<string, number> = {};
for (const addedLink of registry[extensionPointId] ?? []) {
const { pluginId } = addedLink;
// Only limit if the `limitPerPlugin` is set
if (limitPerPlugin && extensionsByPlugin[pluginId] >= limitPerPlugin) {
continue;
}
if (extensionsByPlugin[pluginId] === undefined) {
extensionsByPlugin[pluginId] = 0;
}
// Run the configure() function with the current context, and apply the ovverides
const overrides = getLinkExtensionOverrides(pluginId, addedLink, frozenContext);
// configure() returned an `undefined` -> hide the extension
if (addedLink.configure && overrides === undefined) {
continue;
}
const path = overrides?.path || addedLink.path;
const extension: PluginExtensionLink = {
id: generateExtensionId(pluginId, extensionPointId, addedLink.title),
Plugin extensions: Introduce new registry for added links (#92343) * add added component registry * fix broken test * add tests for usePluginComponents hook * readd expose components * add type assertion exceptions to betterer results * use new addedComponent registry in legacy endpoints * remove unused code * cleanup * revert test code * remove commented code * initial commit * refactor sync method and hook * fix tests * subscribe to the correct registry * remove old registry * cleanup types * add use usePluginLinks hook * add more tests * fix import order * fix typo * fix and temporarly skip failing tests * wip * add hook tests * add more tests * remove old hook * fix versioning * add version to all extension point ids * remove cleanup * remove unused imports * revert touched file * fix test * test: remove hook creation * catch init error * send error to faro * fix broken hook * comment out call hook initialization * use the right import ofr isString * remove unused import * remove registryState type * pr feedback * Update public/app/features/plugins/extensions/validators.test.tsx Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> * Update public/app/features/plugins/extensions/validators.test.tsx Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> * remove no longer relevant comment * fix broken tests * Fixed test to verify that the memotization works properly. * simplify hooks --------- Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
9 months ago
type: PluginExtensionTypes.link,
pluginId: pluginId,
onClick: getLinkExtensionOnClick(pluginId, extensionPointId, addedLink, frozenContext),
// Configurable properties
icon: overrides?.icon || addedLink.icon,
title: overrides?.title || addedLink.title,
description: overrides?.description || addedLink.description,
path: isString(path) ? getLinkExtensionPathWithTracking(pluginId, path, extensionPointId) : undefined,
category: overrides?.category || addedLink.category,
};
extensions.push(extension);
extensionsByPlugin[pluginId] += 1;
}
return {
isLoading: false,
links: extensions,
};
}, [context, extensionPointId, limitPerPlugin, registry]);
};
}