Compare commits
2 Commits
sriram/SQL
...
steady
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
818107d958 | ||
|
|
571e9199fd |
@@ -1,78 +0,0 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
|
||||||
|
|
||||||
import { VizLegendTable } from './VizLegendTable';
|
|
||||||
import { VizLegendItem } from './types';
|
|
||||||
|
|
||||||
describe('VizLegendTable', () => {
|
|
||||||
const mockItems: VizLegendItem[] = [
|
|
||||||
{ label: 'Series 1', color: 'red', yAxis: 1 },
|
|
||||||
{ label: 'Series 2', color: 'blue', yAxis: 1 },
|
|
||||||
{ label: 'Series 3', color: 'green', yAxis: 1 },
|
|
||||||
];
|
|
||||||
|
|
||||||
it('renders without crashing', () => {
|
|
||||||
const { container } = render(<VizLegendTable items={mockItems} placement="bottom" />);
|
|
||||||
expect(container.querySelector('table')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders all items', () => {
|
|
||||||
render(<VizLegendTable items={mockItems} placement="bottom" />);
|
|
||||||
expect(screen.getByText('Series 1')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('Series 2')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('Series 3')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders table headers when items have display values', () => {
|
|
||||||
const itemsWithStats: VizLegendItem[] = [
|
|
||||||
{
|
|
||||||
label: 'Series 1',
|
|
||||||
color: 'red',
|
|
||||||
yAxis: 1,
|
|
||||||
getDisplayValues: () => [
|
|
||||||
{ numeric: 100, text: '100', title: 'Max' },
|
|
||||||
{ numeric: 50, text: '50', title: 'Min' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
render(<VizLegendTable items={itemsWithStats} placement="bottom" />);
|
|
||||||
expect(screen.getByText('Max')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('Min')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders sort icon when sorted', () => {
|
|
||||||
const { container } = render(
|
|
||||||
<VizLegendTable items={mockItems} placement="bottom" sortBy="Name" sortDesc={false} />
|
|
||||||
);
|
|
||||||
expect(container.querySelector('svg')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls onToggleSort when header is clicked', () => {
|
|
||||||
const onToggleSort = jest.fn();
|
|
||||||
render(<VizLegendTable items={mockItems} placement="bottom" onToggleSort={onToggleSort} isSortable={true} />);
|
|
||||||
const header = screen.getByText('Name');
|
|
||||||
header.click();
|
|
||||||
expect(onToggleSort).toHaveBeenCalledWith('Name');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not call onToggleSort when not sortable', () => {
|
|
||||||
const onToggleSort = jest.fn();
|
|
||||||
render(<VizLegendTable items={mockItems} placement="bottom" onToggleSort={onToggleSort} isSortable={false} />);
|
|
||||||
const header = screen.getByText('Name');
|
|
||||||
header.click();
|
|
||||||
expect(onToggleSort).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders with long labels', () => {
|
|
||||||
const itemsWithLongLabels: VizLegendItem[] = [
|
|
||||||
{
|
|
||||||
label: 'This is a very long series name that should be scrollable within its table cell',
|
|
||||||
color: 'red',
|
|
||||||
yAxis: 1,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
render(<VizLegendTable items={itemsWithLongLabels} placement="bottom" />);
|
|
||||||
expect(
|
|
||||||
screen.getByText('This is a very long series name that should be scrollable within its table cell')
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -119,6 +119,7 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
|||||||
table: css({
|
table: css({
|
||||||
width: '100%',
|
width: '100%',
|
||||||
'th:first-child': {
|
'th:first-child': {
|
||||||
|
width: '100%',
|
||||||
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
|
||||||
|
|
||||||
import { LegendTableItem } from './VizLegendTableItem';
|
|
||||||
import { VizLegendItem } from './types';
|
|
||||||
|
|
||||||
describe('LegendTableItem', () => {
|
|
||||||
const mockItem: VizLegendItem = {
|
|
||||||
label: 'Series 1',
|
|
||||||
color: 'red',
|
|
||||||
yAxis: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
it('renders without crashing', () => {
|
|
||||||
const { container } = render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={mockItem} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
expect(container.querySelector('tr')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders label text', () => {
|
|
||||||
render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={mockItem} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
expect(screen.getByText('Series 1')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders with long label text', () => {
|
|
||||||
const longLabelItem: VizLegendItem = {
|
|
||||||
...mockItem,
|
|
||||||
label: 'This is a very long series name that should be scrollable in the table cell',
|
|
||||||
};
|
|
||||||
render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={longLabelItem} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
screen.getByText('This is a very long series name that should be scrollable in the table cell')
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders stat values when provided', () => {
|
|
||||||
const itemWithStats: VizLegendItem = {
|
|
||||||
...mockItem,
|
|
||||||
getDisplayValues: () => [
|
|
||||||
{ numeric: 100, text: '100', title: 'Max' },
|
|
||||||
{ numeric: 50, text: '50', title: 'Min' },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={itemWithStats} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
expect(screen.getByText('100')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('50')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders right y-axis indicator when yAxis is 2', () => {
|
|
||||||
const rightAxisItem: VizLegendItem = {
|
|
||||||
...mockItem,
|
|
||||||
yAxis: 2,
|
|
||||||
};
|
|
||||||
render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={rightAxisItem} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
expect(screen.getByText('(right y-axis)')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls onLabelClick when label is clicked', () => {
|
|
||||||
const onLabelClick = jest.fn();
|
|
||||||
render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={mockItem} onLabelClick={onLabelClick} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
const button = screen.getByRole('button');
|
|
||||||
button.click();
|
|
||||||
expect(onLabelClick).toHaveBeenCalledWith(mockItem, expect.any(Object));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not call onClick when readonly', () => {
|
|
||||||
const onLabelClick = jest.fn();
|
|
||||||
render(
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<LegendTableItem item={mockItem} onLabelClick={onLabelClick} readonly={true} />
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
|
||||||
const button = screen.getByRole('button');
|
|
||||||
expect(button).toBeDisabled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -69,7 +69,7 @@ export const LegendTableItem = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<tr className={cx(styles.row, className)}>
|
<tr className={cx(styles.row, className)}>
|
||||||
<td className={styles.labelCell}>
|
<td>
|
||||||
<span className={styles.itemWrapper}>
|
<span className={styles.itemWrapper}>
|
||||||
<VizLegendSeriesIcon
|
<VizLegendSeriesIcon
|
||||||
color={item.color}
|
color={item.color}
|
||||||
@@ -77,26 +77,24 @@ export const LegendTableItem = ({
|
|||||||
readonly={readonly}
|
readonly={readonly}
|
||||||
lineStyle={item.lineStyle}
|
lineStyle={item.lineStyle}
|
||||||
/>
|
/>
|
||||||
<div className={styles.labelCellInner}>
|
<button
|
||||||
<button
|
disabled={readonly}
|
||||||
disabled={readonly}
|
type="button"
|
||||||
type="button"
|
title={item.label}
|
||||||
title={item.label}
|
onBlur={onMouseOut}
|
||||||
onBlur={onMouseOut}
|
onFocus={onMouseOver}
|
||||||
onFocus={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOut={onMouseOut}
|
||||||
onMouseOut={onMouseOut}
|
onClick={!readonly ? onClick : undefined}
|
||||||
onClick={!readonly ? onClick : undefined}
|
className={cx(styles.label, item.disabled && styles.labelDisabled)}
|
||||||
className={cx(styles.label, item.disabled && styles.labelDisabled)}
|
>
|
||||||
>
|
{item.label}{' '}
|
||||||
{item.label}{' '}
|
{item.yAxis === 2 && (
|
||||||
{item.yAxis === 2 && (
|
<span className={styles.yAxisLabel}>
|
||||||
<span className={styles.yAxisLabel}>
|
<Trans i18nKey="grafana-ui.viz-legend.right-axis-indicator">(right y-axis)</Trans>
|
||||||
<Trans i18nKey="grafana-ui.viz-legend.right-axis-indicator">(right y-axis)</Trans>
|
</span>
|
||||||
</span>
|
)}
|
||||||
)}
|
</button>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
{item.getDisplayValues &&
|
{item.getDisplayValues &&
|
||||||
@@ -130,27 +128,6 @@ const getStyles = (theme: GrafanaTheme2) => {
|
|||||||
background: rowHoverBg,
|
background: rowHoverBg,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
labelCell: css({
|
|
||||||
label: 'LegendLabelCell',
|
|
||||||
maxWidth: 0,
|
|
||||||
width: '100%',
|
|
||||||
}),
|
|
||||||
labelCellInner: css({
|
|
||||||
label: 'LegendLabelCellInner',
|
|
||||||
display: 'block',
|
|
||||||
flex: 1,
|
|
||||||
minWidth: 0,
|
|
||||||
overflowX: 'auto',
|
|
||||||
overflowY: 'hidden',
|
|
||||||
paddingRight: theme.spacing(3),
|
|
||||||
scrollbarWidth: 'none',
|
|
||||||
msOverflowStyle: 'none',
|
|
||||||
maskImage: `linear-gradient(to right, black calc(100% - ${theme.spacing(3)}), transparent 100%)`,
|
|
||||||
WebkitMaskImage: `linear-gradient(to right, black calc(100% - ${theme.spacing(3)}), transparent 100%)`,
|
|
||||||
'&::-webkit-scrollbar': {
|
|
||||||
display: 'none',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
label: css({
|
label: css({
|
||||||
label: 'LegendLabel',
|
label: 'LegendLabel',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
@@ -158,6 +135,9 @@ const getStyles = (theme: GrafanaTheme2) => {
|
|||||||
border: 'none',
|
border: 'none',
|
||||||
fontSize: 'inherit',
|
fontSize: 'inherit',
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
maxWidth: '600px',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
overflow: 'hidden',
|
||||||
userSelect: 'text',
|
userSelect: 'text',
|
||||||
}),
|
}),
|
||||||
labelDisabled: css({
|
labelDisabled: css({
|
||||||
|
|||||||
Reference in New Issue
Block a user