Add to dashboard: expose add to dashboard form component for external apps (#112609)
* add extension for drilldown to add to dashboard * reuse configure add to dashboard function callback * structure for drilldown add to dashboard * fix imports * fix tests * expose as a component * remove extension link * get component ready to extend * lazy load component * add component to exposed component registry * update folder structure to not work in explore folder * keep dependencies clean * nice structure to let folks know this is a drilldown integration * update code owners for new file * make exposed component more generic, step one, update component id * step 2, expose add to dashboard form component * add more explicit useAbsolutePath option to form * remove old implementation code for drilldown specific component * commit translation * add comments to avoid breaking changes * add e2e test for add to dashboard form component * fix flaky test * add exposed component id to e2e test app * remove gridPos in buildPanel fallback fn * add code comment for useAbsolutePath's purpose * remove gridPos from e2e test
This commit is contained in:
@@ -10,6 +10,7 @@ export function ExposedComponents() {
|
||||
const { component: ReusableComponent } = usePluginComponent<ReusableComponentProps>(
|
||||
'grafana-extensionexample1-app/reusable-component/v1'
|
||||
);
|
||||
const { component: AddToDashboardForm } = usePluginComponent('grafana/add-to-dashboard-form/v1');
|
||||
|
||||
if (!ReusableComponent) {
|
||||
return null;
|
||||
@@ -20,6 +21,22 @@ export function ExposedComponents() {
|
||||
<div data-testid={testIds.exposedComponentsPage.container}>
|
||||
<ReusableComponent name={'World'} />
|
||||
</div>
|
||||
{AddToDashboardForm && (
|
||||
<section>
|
||||
<h3>Save to dashboard (exposed form)</h3>
|
||||
<AddToDashboardForm
|
||||
// Create a recognizable panel for assertion
|
||||
buildPanel={() => ({
|
||||
type: 'timeseries',
|
||||
title: 'E2E Add to Dashboard Panel',
|
||||
targets: [],
|
||||
})}
|
||||
// Ensure navigation works correctly from plugin page
|
||||
options={{ useAbsolutePath: true }}
|
||||
onClose={() => {}}
|
||||
/>
|
||||
</section>
|
||||
)}
|
||||
</PluginPage>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
"grafanaDependency": ">=10.4.0",
|
||||
"plugins": [],
|
||||
"extensions": {
|
||||
"exposedComponents": ["grafana-extensionexample1-app/reusable-component/v1"]
|
||||
"exposedComponents": ["grafana-extensionexample1-app/reusable-component/v1", "grafana/add-to-dashboard-form/v1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -1,6 +1,7 @@
|
||||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
import { testIds } from '../testIds';
|
||||
import pluginJson from '../plugin.json';
|
||||
import { ensureExtensionRegistryIsPopulated } from './utils';
|
||||
|
||||
test.describe(
|
||||
'grafana-extensionstest-app',
|
||||
@@ -12,5 +13,34 @@ test.describe(
|
||||
await page.goto(`/a/${pluginJson.id}/exposed-components`);
|
||||
await expect(page.getByTestId(testIds.appB.exposedComponent)).toHaveText('Hello World!');
|
||||
});
|
||||
|
||||
test('exposed add-to-dashboard form saves to a new dashboard', async ({ page }) => {
|
||||
await page.goto(`/a/${pluginJson.id}/exposed-components`);
|
||||
await ensureExtensionRegistryIsPopulated(page);
|
||||
|
||||
// Wait for the exposed form section to be ready
|
||||
await expect(page.getByRole('heading', { name: 'Save to dashboard (exposed form)' })).toBeVisible();
|
||||
|
||||
// Wait for any of the form buttons to render (lazy load) before clicking
|
||||
const openInNewTab = page.getByRole('button', { name: 'Open in new tab' });
|
||||
const cancelBtn = page.getByRole('button', { name: 'Cancel' });
|
||||
await Promise.race([expect(openInNewTab).toBeVisible(), expect(cancelBtn).toBeVisible()]);
|
||||
|
||||
// Now wait for the submit button to be visible, then click (role or text)
|
||||
const openDashboardByRole = page.getByRole('button', { name: 'Open dashboard' });
|
||||
const openDashboardByText = page.getByText('Open dashboard');
|
||||
if (await openDashboardByRole.isVisible().catch(() => false)) {
|
||||
await openDashboardByRole.click();
|
||||
} else {
|
||||
await expect(openDashboardByText.first()).toBeVisible();
|
||||
await openDashboardByText.first().click();
|
||||
}
|
||||
|
||||
// Navigates to /dashboard/new and prepopulates a panel from local storage
|
||||
await expect(page).toHaveURL(/\/dashboard\/new/);
|
||||
|
||||
// Panel should be created with our custom title
|
||||
await expect(page.getByText('E2E Add to Dashboard Panel').first()).toBeVisible();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user