Files
Brendan O'Handley 2472555af0 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
2025-10-29 09:15:20 -05:00

43 lines
1.2 KiB
TypeScript

import { PluginPage, usePluginComponent } from '@grafana/runtime';
import { testIds } from '../testIds';
type ReusableComponentProps = {
name: string;
};
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;
}
return (
<PluginPage>
<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>
);
}