diff --git a/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.test.tsx b/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.test.tsx index 5af933ceec1..df4807a7e67 100644 --- a/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.test.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.test.tsx @@ -313,4 +313,153 @@ describe('DashboardCard', () => { expect(screen.getByRole('heading', { name: 'Community Dashboard' })).toBeInTheDocument(); }); }); + + describe('Compatibility button', () => { + it('should show compatibility button when showCompatibilityButton={true} and onCheckCompatibility is provided', () => { + const mockOnCheckCompatibility = jest.fn(); + render( + + ); + + expect(screen.getByRole('button', { name: 'Check compatibility' })).toBeInTheDocument(); + }); + + it('should not show compatibility button when showCompatibilityButton={false}', () => { + const mockOnCheckCompatibility = jest.fn(); + render( + + ); + + expect(screen.queryByRole('button', { name: 'Check compatibility' })).not.toBeInTheDocument(); + }); + + it('should not show compatibility button when onCheckCompatibility is not provided', () => { + render( + + ); + + expect(screen.queryByRole('button', { name: 'Check compatibility' })).not.toBeInTheDocument(); + }); + + it('should call onCheckCompatibility with dashboard object when button is clicked', async () => { + const mockOnCheckCompatibility = jest.fn(); + const mockDashboard = createMockPluginDashboard(); + const { user } = render( + + ); + + await user.click(screen.getByRole('button', { name: 'Check compatibility' })); + + expect(mockOnCheckCompatibility).toHaveBeenCalledTimes(1); + expect(mockOnCheckCompatibility).toHaveBeenCalledWith(mockDashboard); + }); + + it('should prevent event propagation when compatibility button is clicked', async () => { + const mockOnCheckCompatibility = jest.fn(); + const mockParentClick = jest.fn(); + const { user } = render( +
+ +
+ ); + + await user.click(screen.getByRole('button', { name: 'Check compatibility' })); + + expect(mockParentClick).not.toHaveBeenCalled(); + expect(mockOnCheckCompatibility).toHaveBeenCalledTimes(1); + }); + + it('should display compatibility tooltip on hover', async () => { + const mockOnCheckCompatibility = jest.fn(); + const { user } = render( + + ); + + const button = screen.getByRole('button', { name: 'Check compatibility' }); + await user.hover(button); + + expect(await screen.findByText('Check dashboard compatibility with your datasource')).toBeInTheDocument(); + }); + + it('should render and work with GnetDashboard type', async () => { + const mockOnCheckCompatibility = jest.fn(); + const mockDashboard = createMockGnetDashboard({ name: 'Community Dashboard' }); + const { user } = render( + + ); + + await user.click(screen.getByRole('button', { name: 'Check compatibility' })); + + expect(mockOnCheckCompatibility).toHaveBeenCalledWith(mockDashboard); + }); + + it('should render buttons in correct order: primary, details, compatibility', () => { + const mockOnCheckCompatibility = jest.fn(); + const details = createMockDetails(); + render( + + ); + + const buttons = screen.getAllByRole('button'); + expect(buttons[0]).toHaveTextContent('Use dashboard'); + expect(buttons[1]).toHaveAttribute('aria-label', 'Details'); + expect(buttons[2]).toHaveAttribute('aria-label', 'Check compatibility'); + }); + }); }); diff --git a/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.tsx b/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.tsx index 4d992320c09..3943ed296b3 100644 --- a/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardLibrary/DashboardCard.tsx @@ -28,6 +28,8 @@ interface Props { showDatasourceProvidedBadge?: boolean; dimThumbnail?: boolean; // Apply 50% opacity to thumbnail when badge is shown kind: 'template_dashboard' | 'suggested_dashboard'; + onCheckCompatibility?: (dashboard: PluginDashboard | GnetDashboard) => void; + showCompatibilityButton?: boolean; } function DashboardCardComponent({ @@ -40,6 +42,8 @@ function DashboardCardComponent({ showDatasourceProvidedBadge, dimThumbnail, kind, + onCheckCompatibility, + showCompatibilityButton, }: Props) { const styles = useStyles2(getStyles); @@ -99,6 +103,25 @@ function DashboardCardComponent({ /> )} + {showCompatibilityButton && onCheckCompatibility && ( + +