Add 'Check Compatibility' button to DashboardCard"

This commit is contained in:
alexandra vargas
2026-01-06 15:41:26 +01:00
parent 92041e5a05
commit c9e044b2c7
2 changed files with 172 additions and 0 deletions
@@ -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(
<DashboardCard
title="Test Dashboard"
dashboard={createMockPluginDashboard()}
onClick={mockOnClick}
showCompatibilityButton={true}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
);
expect(screen.getByRole('button', { name: 'Check compatibility' })).toBeInTheDocument();
});
it('should not show compatibility button when showCompatibilityButton={false}', () => {
const mockOnCheckCompatibility = jest.fn();
render(
<DashboardCard
title="Test Dashboard"
dashboard={createMockPluginDashboard()}
onClick={mockOnClick}
showCompatibilityButton={false}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
);
expect(screen.queryByRole('button', { name: 'Check compatibility' })).not.toBeInTheDocument();
});
it('should not show compatibility button when onCheckCompatibility is not provided', () => {
render(
<DashboardCard
title="Test Dashboard"
dashboard={createMockPluginDashboard()}
onClick={mockOnClick}
showCompatibilityButton={true}
kind="suggested_dashboard"
/>
);
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(
<DashboardCard
title="Test Dashboard"
dashboard={mockDashboard}
onClick={mockOnClick}
showCompatibilityButton={true}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
);
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(
<div onClick={mockParentClick}>
<DashboardCard
title="Test Dashboard"
dashboard={createMockPluginDashboard()}
onClick={mockOnClick}
showCompatibilityButton={true}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
</div>
);
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(
<DashboardCard
title="Test Dashboard"
dashboard={createMockPluginDashboard()}
onClick={mockOnClick}
showCompatibilityButton={true}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
);
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(
<DashboardCard
title="Community Dashboard"
dashboard={mockDashboard}
onClick={mockOnClick}
showCompatibilityButton={true}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
);
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(
<DashboardCard
title="Test Dashboard"
dashboard={createMockPluginDashboard()}
onClick={mockOnClick}
details={details}
showCompatibilityButton={true}
onCheckCompatibility={mockOnCheckCompatibility}
kind="suggested_dashboard"
/>
);
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');
});
});
});
@@ -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({
/>
</Tooltip>
)}
{showCompatibilityButton && onCheckCompatibility && (
<Tooltip
content={t(
'dashboard-library.card.check-compatibility-tooltip',
'Check dashboard compatibility with your datasource'
)}
placement="top"
>
<Button
variant="secondary"
icon="check-circle"
onClick={(e) => {
e.stopPropagation();
onCheckCompatibility(dashboard);
}}
aria-label={t('dashboard-library.card.check-compatibility-button', 'Check compatibility')}
/>
</Tooltip>
)}
</Card.Actions>
</Card>
);