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>
This commit is contained in:
co-authored by
Levente Balogh
Marcus Andersson
parent
16c618f4d3
commit
db0cc24f2b
@@ -1,25 +1,22 @@
|
||||
import { PluginPage, usePluginLinks } from '@grafana/runtime';
|
||||
import { Stack } from '@grafana/ui';
|
||||
|
||||
import { ActionButton } from '../components/ActionButton';
|
||||
import { testIds } from '../testIds';
|
||||
|
||||
export const LINKS_EXTENSION_POINT_ID = 'plugins/grafana-extensionstest-app/use-plugin-links/v1';
|
||||
|
||||
export function AddedLinks() {
|
||||
const { links, isLoading } = usePluginLinks({ extensionPointId: LINKS_EXTENSION_POINT_ID });
|
||||
const { links } = usePluginLinks({ extensionPointId: LINKS_EXTENSION_POINT_ID });
|
||||
|
||||
return (
|
||||
<PluginPage>
|
||||
<div data-testid={testIds.addedLinksPage.container}>
|
||||
{isLoading ? (
|
||||
<div>Loading...</div>
|
||||
) : (
|
||||
links.map(({ id, title, path, onClick }) => (
|
||||
<a href={path} title={title} key={id} onClick={onClick}>
|
||||
{title}
|
||||
</a>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
<Stack direction={'column'} gap={4} data-testid={testIds.addedLinksPage.container}>
|
||||
<section data-testid={testIds.addedLinksPage.section1}>
|
||||
<h3>Link extensions defined with addLink and retrieved using usePluginLinks</h3>
|
||||
<ActionButton extensions={links} />
|
||||
</section>
|
||||
</Stack>
|
||||
</PluginPage>
|
||||
);
|
||||
}
|
||||
|
||||
+7
-2
@@ -4,7 +4,6 @@ import { LINKS_EXTENSION_POINT_ID } from '../../pages/AddedLinks';
|
||||
import { testIds } from '../../testIds';
|
||||
|
||||
import { App } from './components/App';
|
||||
import pluginJson from './plugin.json';
|
||||
|
||||
export const plugin = new AppPlugin<{}>()
|
||||
.setRootPage(App)
|
||||
@@ -24,5 +23,11 @@ export const plugin = new AppPlugin<{}>()
|
||||
title: 'Basic link',
|
||||
description: '...',
|
||||
targets: [LINKS_EXTENSION_POINT_ID],
|
||||
path: `/a/${pluginJson.id}/`,
|
||||
path: '/a/grafana-extensionexample1-app/',
|
||||
})
|
||||
.addLink({
|
||||
title: 'Go to A',
|
||||
description: 'Navigating to pluging A',
|
||||
targets: [LINKS_EXTENSION_POINT_ID],
|
||||
path: '/a/grafana-extensionexample1-app/',
|
||||
});
|
||||
|
||||
+12
@@ -1,5 +1,6 @@
|
||||
import { AppPlugin } from '@grafana/data';
|
||||
|
||||
import { LINKS_EXTENSION_POINT_ID } from '../../pages/AddedLinks';
|
||||
import { testIds } from '../../testIds';
|
||||
|
||||
import { App } from './components/App';
|
||||
@@ -30,4 +31,15 @@ export const plugin = new AppPlugin<{}>()
|
||||
component: ({ name }: { name: string }) => (
|
||||
<div data-testid={testIds.appB.reusableAddedComponent}>Hello {name}!</div>
|
||||
),
|
||||
})
|
||||
.addLink({
|
||||
title: 'Open from B',
|
||||
description: 'Open a modal from plugin B',
|
||||
targets: [LINKS_EXTENSION_POINT_ID],
|
||||
onClick: (_, { openModal }) => {
|
||||
openModal({
|
||||
title: 'Modal from app B',
|
||||
body: () => <div data-testid={testIds.appB.modal}>From plugin B</div>,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -36,5 +36,6 @@ export const testIds = {
|
||||
},
|
||||
addedLinksPage: {
|
||||
container: 'data-testid pg-added-links-container',
|
||||
section1: 'use-plugin-links',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,8 +3,28 @@ import { test, expect } from '@grafana/plugin-e2e';
|
||||
import pluginJson from '../plugin.json';
|
||||
import { testIds } from '../testIds';
|
||||
|
||||
test('path link', async ({ page }) => {
|
||||
test('should extend the actions menu with a link to a-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/added-links`);
|
||||
await page.getByTestId(testIds.addedLinksPage.container).getByText('Basic link').click();
|
||||
await expect(page.getByTestId(testIds.appA.container)).toHaveText('Hello Grafana!');
|
||||
const section = await page.getByTestId(testIds.addedLinksPage.section1);
|
||||
await section.getByTestId(testIds.actions.button).click();
|
||||
await page.getByTestId(testIds.container).getByText('Go to A').click();
|
||||
await page.getByTestId(testIds.modal.open).click();
|
||||
await expect(page.getByTestId(testIds.appA.container)).toBeVisible();
|
||||
});
|
||||
|
||||
test('should extend main app with link extension from app B', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/added-links`);
|
||||
const section = await page.getByTestId(testIds.addedLinksPage.section1);
|
||||
await section.getByTestId(testIds.actions.button).click();
|
||||
await page.getByTestId(testIds.container).getByText('Open from B').click();
|
||||
await expect(page.getByTestId(testIds.appB.modal)).toBeVisible();
|
||||
});
|
||||
|
||||
test('should extend main app with basic link extension from app A', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/added-links`);
|
||||
const section = await page.getByTestId(testIds.addedLinksPage.section1);
|
||||
await section.getByTestId(testIds.actions.button).click();
|
||||
await page.getByTestId(testIds.container).getByText('Basic link').click();
|
||||
await page.getByTestId(testIds.modal.open).click();
|
||||
await expect(page.getByTestId(testIds.appA.container)).toBeVisible();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user