Plugin Extensions: Clean up the deprecated APIs (#102102)
* PanelMenuBehaviour: stop using the deprecated `getPluginLinkExtensions()` API * Wip * grafana-runtime: remove deprecated APIs `usePluginExtensions()`, `usePluginLinkExtensions()` and `usePluginComponentExtensions()` * Wip * Wip * wip * wip * Chore: removed PluginExtensionLinkConfig * Chore: removed PluginExtensionComponentConfig * Chore: fixed grafana-pyroscope-datasource QueryEditor test * Chore: fixed PublicDashboardScenePage.test.tsx * Chore: fix PanelDataQueriesTab test * Chore: fix PanelMenuBehavior test * Chore: fix transformSceneToSaveModel test * Chore: fix last type errors * Chore: fix alerting/unified/testSetup/plugins.ts * Chore: break out types to separate file * feat(Extensions): expose an observable API for added links and components * chore: prettier fixes * Revert "chore: prettier fixes" This reverts commit53aa767664. * Revert "feat(Extensions): expose an observable API for added links and components" This reverts commitbdc588250e. --------- Co-authored-by: Hugo Häggmark <hugo.haggmark@gmail.com>
This commit is contained in:
co-authored by
Hugo Häggmark
parent
c1cadc7d6f
commit
39dcff23f9
@@ -3,20 +3,18 @@ import { Route, Routes } from 'react-router-dom';
|
||||
import { AppRootProps } from '@grafana/data';
|
||||
|
||||
import { ROUTES } from '../../constants';
|
||||
import { AddedComponents, AddedLinks, ExposedComponents, LegacyGetters, LegacyHooks } from '../../pages';
|
||||
import { AddedComponents, AddedLinks, ExposedComponents } from '../../pages';
|
||||
import { testIds } from '../../testIds';
|
||||
|
||||
export function App(props: AppRootProps) {
|
||||
return (
|
||||
<div data-testid={testIds.container} style={{ marginTop: '5%' }}>
|
||||
<Routes>
|
||||
<Route path={ROUTES.LegacyGetters} element={<LegacyGetters />} />
|
||||
<Route path={ROUTES.LegacyHooks} element={<LegacyHooks />} />
|
||||
<Route path={ROUTES.ExposedComponents} element={<ExposedComponents />} />
|
||||
<Route path={ROUTES.AddedComponents} element={<AddedComponents />} />
|
||||
<Route path={ROUTES.AddedLinks} element={<AddedLinks />} />
|
||||
|
||||
<Route path={'*'} element={<LegacyGetters />} />
|
||||
<Route path={'*'} element={<ExposedComponents />} />
|
||||
</Routes>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -6,10 +6,10 @@ import pluginJson from './plugin.json';
|
||||
|
||||
export const plugin = new AppPlugin<{}>()
|
||||
.setRootPage(App)
|
||||
.configureExtensionLink<PluginExtensionPanelContext>({
|
||||
.addLink<PluginExtensionPanelContext>({
|
||||
title: 'Open from time series or pie charts (path)',
|
||||
description: 'This link will only be visible on time series and pie charts',
|
||||
extensionPointId: PluginExtensionPoints.DashboardPanelMenu,
|
||||
targets: PluginExtensionPoints.DashboardPanelMenu,
|
||||
path: `/a/${pluginJson.id}/`,
|
||||
configure: (context) => {
|
||||
// Will only be visible for the Link Extensions dashboard
|
||||
@@ -31,10 +31,10 @@ export const plugin = new AppPlugin<{}>()
|
||||
}
|
||||
},
|
||||
})
|
||||
.configureExtensionLink<PluginExtensionPanelContext>({
|
||||
.addLink<PluginExtensionPanelContext>({
|
||||
title: 'Open from time series or pie charts (onClick)',
|
||||
description: 'This link will only be visible on time series and pie charts',
|
||||
extensionPointId: PluginExtensionPoints.DashboardPanelMenu,
|
||||
targets: PluginExtensionPoints.DashboardPanelMenu,
|
||||
onClick: (_, { openModal, context }) => {
|
||||
const targets = context?.targets ?? [];
|
||||
const title = context?.title;
|
||||
|
||||
@@ -42,6 +42,5 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@grafana/runtime": "*"
|
||||
},
|
||||
"packageManager": "yarn@4.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import {
|
||||
PluginPage,
|
||||
getPluginComponentExtensions,
|
||||
getPluginExtensions,
|
||||
getPluginLinkExtensions,
|
||||
} from '@grafana/runtime';
|
||||
import { Stack } from '@grafana/ui';
|
||||
|
||||
import { ActionButton } from '../components/ActionButton';
|
||||
import { testIds } from '../testIds';
|
||||
|
||||
type AppExtensionContext = {};
|
||||
type ReusableComponentProps = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export function LegacyGetters() {
|
||||
const extensionPointId1 = 'plugins/grafana-extensionstest-app/actions';
|
||||
const extensionPointId2 = 'plugins/grafana-extensionstest-app/configure-extension-component/v1';
|
||||
const context: AppExtensionContext = {};
|
||||
|
||||
const { extensions } = getPluginExtensions({
|
||||
extensionPointId: extensionPointId1,
|
||||
context,
|
||||
});
|
||||
|
||||
const { extensions: linkExtensions } = getPluginLinkExtensions({
|
||||
extensionPointId: extensionPointId1,
|
||||
});
|
||||
|
||||
const { extensions: componentExtensions } = getPluginComponentExtensions<ReusableComponentProps>({
|
||||
extensionPointId: extensionPointId2,
|
||||
});
|
||||
|
||||
return (
|
||||
<PluginPage>
|
||||
<Stack direction={'column'} gap={4} data-testid={testIds.legacyGettersPage.container}>
|
||||
<section data-testid={testIds.legacyGettersPage.section1}>
|
||||
<h3>
|
||||
Link extensions defined with configureExtensionLink or configureExtensionComponent and retrived using
|
||||
getPluginExtensions
|
||||
</h3>
|
||||
<ActionButton extensions={extensions} />
|
||||
</section>
|
||||
<section data-testid={testIds.legacyGettersPage.section2}>
|
||||
<h3>Link extensions defined with configureExtensionLink and retrived using getPluginLinkExtensions</h3>
|
||||
<ActionButton extensions={linkExtensions} />
|
||||
</section>
|
||||
<section data-testid={testIds.legacyGettersPage.section3}>
|
||||
<h3>
|
||||
Component extensions defined with configureExtensionComponent and retrived using
|
||||
getPluginComponentExtensions
|
||||
</h3>
|
||||
{componentExtensions.map((extension) => {
|
||||
const Component = extension.component;
|
||||
return <Component key={extension.id} name="World" />;
|
||||
})}
|
||||
</section>
|
||||
</Stack>
|
||||
</PluginPage>
|
||||
);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import {
|
||||
PluginPage,
|
||||
usePluginComponentExtensions,
|
||||
usePluginExtensions,
|
||||
usePluginLinkExtensions,
|
||||
} from '@grafana/runtime';
|
||||
import { Stack } from '@grafana/ui';
|
||||
|
||||
import { ActionButton } from '../components/ActionButton';
|
||||
import { testIds } from '../testIds';
|
||||
|
||||
type AppExtensionContext = {};
|
||||
type ReusableComponentProps = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export function LegacyHooks() {
|
||||
const extensionPointId1 = 'plugins/grafana-extensionstest-app/actions';
|
||||
const extensionPointId2 = 'plugins/grafana-extensionstest-app/configure-extension-component/v1';
|
||||
const context: AppExtensionContext = {};
|
||||
|
||||
const { extensions } = usePluginExtensions({
|
||||
extensionPointId: extensionPointId1,
|
||||
context,
|
||||
});
|
||||
|
||||
const { extensions: linkExtensions } = usePluginLinkExtensions({
|
||||
extensionPointId: extensionPointId1,
|
||||
});
|
||||
|
||||
const { extensions: componentExtensions } = usePluginComponentExtensions<ReusableComponentProps>({
|
||||
extensionPointId: extensionPointId2,
|
||||
});
|
||||
|
||||
return (
|
||||
<PluginPage>
|
||||
<Stack direction={'column'} gap={4} data-testid={testIds.legacyHooksPage.container}>
|
||||
<section data-testid={testIds.legacyHooksPage.section1}>
|
||||
<h3>
|
||||
Link extensions defined with configureExtensionLink or configureExtensionComponent and retrived using
|
||||
usePluginExtensions
|
||||
</h3>
|
||||
<ActionButton extensions={extensions} />
|
||||
</section>
|
||||
<section data-testid={testIds.legacyHooksPage.section2}>
|
||||
<h3>Link extensions defined with configureExtensionLink and retrived using usePluginLinkExtensions</h3>
|
||||
<ActionButton extensions={linkExtensions} />
|
||||
</section>
|
||||
<section data-testid={testIds.legacyHooksPage.section3}>
|
||||
<h3>
|
||||
Component extensions defined with configureExtensionComponent and retrived using
|
||||
usePluginComponentExtensions
|
||||
</h3>
|
||||
{componentExtensions.map((extension) => {
|
||||
const Component = extension.component;
|
||||
return <Component key={extension.id} name="World" />;
|
||||
})}
|
||||
</section>
|
||||
</Stack>
|
||||
</PluginPage>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
export { ExposedComponents } from './ExposedComponents';
|
||||
export { LegacyGetters } from './LegacyGetters';
|
||||
export { LegacyHooks } from './LegacyHooks';
|
||||
export { AddedComponents } from './AddedComponents';
|
||||
export { AddedLinks } from './AddedLinks';
|
||||
|
||||
@@ -19,22 +19,6 @@
|
||||
"updated": "%TODAY%"
|
||||
},
|
||||
"includes": [
|
||||
{
|
||||
"type": "page",
|
||||
"name": "Legacy Getters",
|
||||
"path": "/a/grafana-extensionstest-app/legacy-getters",
|
||||
"role": "Admin",
|
||||
"addToNav": true,
|
||||
"defaultNav": false
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"name": "Legacy Hooks",
|
||||
"path": "/a/grafana-extensionstest-app/legacy-hooks",
|
||||
"role": "Admin",
|
||||
"addToNav": true,
|
||||
"defaultNav": false
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"name": "Exposed components",
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ export class App extends React.PureComponent<AppRootProps> {
|
||||
render() {
|
||||
return (
|
||||
<div data-testid={testIds.appA.container} className="page-container">
|
||||
Hello Grafana!
|
||||
Hello Grafana!!!!!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
-6
@@ -7,12 +7,6 @@ import { App } from './components/App';
|
||||
|
||||
export const plugin = new AppPlugin<{}>()
|
||||
.setRootPage(App)
|
||||
.configureExtensionLink({
|
||||
title: 'Go to A',
|
||||
description: 'Navigating to pluging A',
|
||||
extensionPointId: 'plugins/grafana-extensionstest-app/actions',
|
||||
path: '/a/grafana-extensionexample1-app/',
|
||||
})
|
||||
.exposeComponent({
|
||||
id: 'grafana-extensionexample1-app/reusable-component/v1',
|
||||
title: 'Exposed component',
|
||||
|
||||
-17
@@ -7,23 +7,6 @@ import { App } from './components/App';
|
||||
|
||||
export const plugin = new AppPlugin<{}>()
|
||||
.setRootPage(App)
|
||||
.configureExtensionLink({
|
||||
title: 'Open from B',
|
||||
description: 'Open a modal from plugin B',
|
||||
extensionPointId: 'plugins/grafana-extensionstest-app/actions',
|
||||
onClick: (_, { openModal }) => {
|
||||
openModal({
|
||||
title: 'Modal from app B',
|
||||
body: () => <div data-testid={testIds.appB.modal}>From plugin B</div>,
|
||||
});
|
||||
},
|
||||
})
|
||||
.configureExtensionComponent({
|
||||
extensionPointId: 'plugins/grafana-extensionstest-app/configure-extension-component/v1',
|
||||
title: 'Configure extension component from B',
|
||||
description: 'A component that can be reused by other app plugins. Shared using configureExtensionComponent api',
|
||||
component: ({ name }: { name: string }) => <div data-testid={testIds.appB.reusableComponent}>Hello {name}!</div>,
|
||||
})
|
||||
.addComponent<{ name: string }>({
|
||||
targets: 'plugins/grafana-extensionstest-app/addComponent/v1',
|
||||
title: 'Added component from B',
|
||||
|
||||
+1
-7
@@ -1,4 +1,4 @@
|
||||
import { usePluginExtensions, usePluginLinks } from '@grafana/runtime';
|
||||
import { usePluginLinks } from '@grafana/runtime';
|
||||
import { Stack } from '@grafana/ui';
|
||||
import { testIds } from '../../../../testIds';
|
||||
import { ActionButton } from '../../../../components/ActionButton';
|
||||
@@ -7,18 +7,12 @@ export const LINKS_EXTENSION_POINT_ID = 'plugins/grafana-extensionstest-app/use-
|
||||
|
||||
export function AddedLinks() {
|
||||
const { links } = usePluginLinks({ extensionPointId: LINKS_EXTENSION_POINT_ID });
|
||||
const { extensions } = usePluginExtensions({ extensionPointId: LINKS_EXTENSION_POINT_ID });
|
||||
|
||||
return (
|
||||
<Stack direction={'column'} gap={4}>
|
||||
<section data-testid={testIds.appC.section1}>
|
||||
<h3>Link extensions defined with addLink and retrieved using usePluginLinks</h3>
|
||||
<ActionButton extensions={links} />
|
||||
</section>
|
||||
<section data-testid={testIds.appC.section2}>
|
||||
<h3>Link extensions defined with addLink and retrieved using usePluginExtensions</h3>
|
||||
<ActionButton extensions={extensions} />
|
||||
</section>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
-17
@@ -6,23 +6,6 @@ import { App } from '../../components/App';
|
||||
|
||||
export const plugin = new AppPlugin<{}>()
|
||||
.setRootPage(App)
|
||||
.configureExtensionLink({
|
||||
title: 'configureExtensionLink (where meta data is missing)',
|
||||
description: 'Open a modal from plugin B',
|
||||
extensionPointId: 'plugins/grafana-extensionstest-app/actions',
|
||||
onClick: (_, { openModal }) => {
|
||||
openModal({
|
||||
title: 'Modal from app B',
|
||||
body: () => <div data-testid={testIds.appB.modal}>From plugin B</div>,
|
||||
});
|
||||
},
|
||||
})
|
||||
.configureExtensionComponent({
|
||||
extensionPointId: 'plugins/grafana-extensionstest-app/configure-extension-component/v1',
|
||||
title: 'configureExtensionComponent (where meta data is missing)',
|
||||
description: 'A component that can be reused by other app plugins. Shared using configureExtensionComponent api',
|
||||
component: ({ name }: { name: string }) => <div data-testid={testIds.appB.reusableComponent}>Hello {name}!</div>,
|
||||
})
|
||||
.addComponent<{ name: string }>({
|
||||
targets: ['plugins/grafana-extensionstest-app/addComponent/v1'],
|
||||
title: 'Added component (where meta data is missing)',
|
||||
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
import { ensureExtensionRegistryIsPopulated } from '../utils';
|
||||
import { testIds } from '../../testIds';
|
||||
import pluginJson from '../../plugin.json';
|
||||
|
||||
test.describe('getPluginExtensions + configureExtensionLink', () => {
|
||||
test('should extend the actions menu with a link to a-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-getters`);
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
const section = await page.getByTestId(testIds.legacyGettersPage.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.describe('getPluginExtensions + configureExtensionComponent', () => {
|
||||
test('should extend main app with component extension from app B', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-getters`);
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
const section = await page.getByTestId(testIds.legacyGettersPage.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.describe('getPluginLinkExtensions + configureExtensionLink', () => {
|
||||
test('should extend the actions menu with a link to a-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-getters`);
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
const section = await page.getByTestId(testIds.legacyGettersPage.section2);
|
||||
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.describe('getPluginComponentExtensions + configureExtensionComponent', () => {
|
||||
test('should extend the actions menu with a command triggered from b-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-getters`);
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
await expect(
|
||||
page
|
||||
.getByTestId('configure-extension-component-get-plugin-component-extensions')
|
||||
.getByTestId(testIds.appB.reusableComponent)
|
||||
).toHaveText('Hello World!');
|
||||
});
|
||||
});
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
import { testIds } from '../../testIds';
|
||||
import pluginJson from '../../plugin.json';
|
||||
import testApp3pluginJson from '../../plugins/grafana-extensionexample3-app/plugin.json';
|
||||
|
||||
test.describe('usePluginExtensions + configureExtensionLink', () => {
|
||||
test('should extend the actions menu with a link to a-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-hooks`);
|
||||
const section = await page.getByTestId(testIds.legacyHooksPage.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 not display extensions that have not been declared in plugin.json when in development mode', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-hooks`);
|
||||
const section = await page.getByTestId(testIds.legacyHooksPage.section1);
|
||||
await section.getByTestId(testIds.actions.button).click();
|
||||
await expect(
|
||||
page.getByTestId(testIds.container).getByText('configureExtensionLink (where meta data is missing)')
|
||||
).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('usePluginExtensions + configureExtensionComponent', () => {
|
||||
test('should extend main app with component extension from app B', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-hooks`);
|
||||
const section = await page.getByTestId(testIds.legacyHooksPage.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.describe('usePluginLinkExtensions + configureExtensionLink', () => {
|
||||
test('should extend the actions menu with a link to a-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-hooks`);
|
||||
const section = await page.getByTestId(testIds.legacyHooksPage.section2);
|
||||
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.describe('usePluginComponentExtensions + configureExtensionComponent', () => {
|
||||
test('should extend the actions menu with a command triggered from b-app plugin', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/legacy-hooks`);
|
||||
await expect(
|
||||
page.getByTestId(testIds.legacyHooksPage.section3).getByTestId(testIds.appB.reusableComponent)
|
||||
).toHaveText('Hello World!');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('usePluginExtensions + addLink', () => {
|
||||
test('should not display extensions in case extension point has not been declared in plugin json (dev mode only)', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(`/a/${testApp3pluginJson.id}/legacy-hooks`);
|
||||
const section = await page.getByTestId(testIds.appC.section2);
|
||||
await expect(section.getByTestId(testIds.actions.button)).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
import { expect, test } from '@grafana/plugin-e2e';
|
||||
import { ensureExtensionRegistryIsPopulated } from '../utils';
|
||||
|
||||
const panelTitle = 'Link with defaults';
|
||||
const extensionTitle = 'Open from time series...';
|
||||
|
||||
const linkOnClickDashboardUid = 'dbfb47c5-e5e5-4d28-8ac7-35f349b95946';
|
||||
const linkPathDashboardUid = 'd1fbb077-cd44-4738-8c8a-d4e66748b719';
|
||||
|
||||
test.describe('configureExtensionLink targeting core extension points', () => {
|
||||
test('configureExtensionLink - should add link extension (path) with defaults to time series panel.', async ({
|
||||
gotoDashboardPage,
|
||||
page,
|
||||
}) => {
|
||||
const dashboardPage = await gotoDashboardPage({ uid: linkPathDashboardUid });
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
const panel = await dashboardPage.getPanelByTitle(panelTitle);
|
||||
await panel.clickOnMenuItem(extensionTitle, { parentItem: 'Extensions' });
|
||||
await expect(page.getByRole('heading', { name: 'Extensions test app' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('should add link extension (onclick) with defaults to time series panel', async ({
|
||||
gotoDashboardPage,
|
||||
page,
|
||||
}) => {
|
||||
const dashboardPage = await gotoDashboardPage({ uid: linkOnClickDashboardUid });
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
const panel = await dashboardPage.getPanelByTitle(panelTitle);
|
||||
await panel.clickOnMenuItem(extensionTitle, { parentItem: 'Extensions' });
|
||||
await expect(page.getByRole('dialog')).toContainText('Select query from "Link with defaults"');
|
||||
});
|
||||
|
||||
test('should add link extension (onclick) with new title to pie chart panel', async ({ gotoDashboardPage, page }) => {
|
||||
const panelTitle = 'Link with new name';
|
||||
const extensionTitle = 'Open from piechart';
|
||||
const dashboardPage = await gotoDashboardPage({ uid: linkOnClickDashboardUid });
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
const panel = await dashboardPage.getPanelByTitle(panelTitle);
|
||||
await panel.clickOnMenuItem(extensionTitle, { parentItem: 'Extensions' });
|
||||
await expect(page.getByRole('dialog')).toContainText('Select query from "Link with new name"');
|
||||
});
|
||||
});
|
||||
@@ -37,3 +37,35 @@ test('should not display any extensions when extension point is not declared in
|
||||
const container = await page.getByTestId(testIds.appC.section1);
|
||||
await expect(container.getByTestId(testIds.actions.button)).not.toBeVisible();
|
||||
});
|
||||
|
||||
const panelTitle = 'Link with defaults';
|
||||
const extensionTitle = 'Open from time series...';
|
||||
|
||||
const linkOnClickDashboardUid = 'dbfb47c5-e5e5-4d28-8ac7-35f349b95946';
|
||||
const linkPathDashboardUid = 'd1fbb077-cd44-4738-8c8a-d4e66748b719';
|
||||
|
||||
test('configureExtensionLink - should add link extension (path) with defaults to time series panel.', async ({
|
||||
gotoDashboardPage,
|
||||
page,
|
||||
}) => {
|
||||
const dashboardPage = await gotoDashboardPage({ uid: linkPathDashboardUid });
|
||||
const panel = await dashboardPage.getPanelByTitle(panelTitle);
|
||||
await panel.clickOnMenuItem(extensionTitle, { parentItem: 'Extensions' });
|
||||
await expect(page.getByRole('heading', { name: 'Extensions test app' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('should add link extension (onclick) with defaults to time series panel', async ({ gotoDashboardPage, page }) => {
|
||||
const dashboardPage = await gotoDashboardPage({ uid: linkOnClickDashboardUid });
|
||||
const panel = await dashboardPage.getPanelByTitle(panelTitle);
|
||||
await panel.clickOnMenuItem(extensionTitle, { parentItem: 'Extensions' });
|
||||
await expect(page.getByRole('dialog')).toContainText('Select query from "Link with defaults"');
|
||||
});
|
||||
|
||||
test('should add link extension (onclick) with new title to pie chart panel', async ({ gotoDashboardPage, page }) => {
|
||||
const panelTitle = 'Link with new name';
|
||||
const extensionTitle = 'Open from piechart';
|
||||
const dashboardPage = await gotoDashboardPage({ uid: linkOnClickDashboardUid });
|
||||
const panel = await dashboardPage.getPanelByTitle(panelTitle);
|
||||
await panel.clickOnMenuItem(extensionTitle, { parentItem: 'Extensions' });
|
||||
await expect(page.getByRole('dialog')).toContainText('Select query from "Link with new name"');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user