Files
grafana/public/app/features/plugins/extensions/usePluginComponents.tsx
Erik Sundell db0cc24f2b 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>
2024-08-30 10:09:01 +02:00

48 lines
1.5 KiB
TypeScript

import { useMemo } from 'react';
import { useObservable } from 'react-use';
import {
UsePluginComponentOptions,
UsePluginComponentsResult,
} from '@grafana/runtime/src/services/pluginExtensions/getPluginExtensions';
import { AddedComponentsRegistry } from './registry/AddedComponentsRegistry';
// Returns an array of component extensions for the given extension point
export function createUsePluginComponents(registry: AddedComponentsRegistry) {
const observableRegistry = registry.asObservable();
return function usePluginComponents<Props extends object = {}>({
limitPerPlugin,
extensionPointId,
}: UsePluginComponentOptions): UsePluginComponentsResult<Props> {
const registry = useObservable(observableRegistry);
return useMemo(() => {
const components: Array<React.ComponentType<Props>> = [];
const extensionsByPlugin: Record<string, number> = {};
for (const registryItem of registry?.[extensionPointId] ?? []) {
const { pluginId } = registryItem;
// Only limit if the `limitPerPlugin` is set
if (limitPerPlugin && extensionsByPlugin[pluginId] >= limitPerPlugin) {
continue;
}
if (extensionsByPlugin[pluginId] === undefined) {
extensionsByPlugin[pluginId] = 0;
}
components.push(registryItem.component as React.ComponentType<Props>);
extensionsByPlugin[pluginId] += 1;
}
return {
isLoading: false,
components,
};
}, [extensionPointId, limitPerPlugin, registry]);
};
}