mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Table: Fixes so links work for image cells (#32370)
* Panel/Table: Adjust data links logic Closes #31576
This commit is contained in:
parent
ab4b980d54
commit
2827d89ccf
@ -1,5 +1,5 @@
|
|||||||
import React, { FC, MouseEventHandler, ReactElement } from 'react';
|
import React, { FC, ReactElement } from 'react';
|
||||||
import { DisplayValue, Field, formattedValueToString, LinkModel } from '@grafana/data';
|
import { DisplayValue, Field, formattedValueToString } from '@grafana/data';
|
||||||
|
|
||||||
import { TableCellDisplayMode, TableCellProps } from './types';
|
import { TableCellDisplayMode, TableCellProps } from './types';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
@ -8,7 +8,7 @@ import { FilterActions } from './FilterActions';
|
|||||||
import { getTextColorForBackground } from '../../utils';
|
import { getTextColorForBackground } from '../../utils';
|
||||||
|
|
||||||
export const DefaultCell: FC<TableCellProps> = (props) => {
|
export const DefaultCell: FC<TableCellProps> = (props) => {
|
||||||
const { field, cell, tableStyles, row, cellProps } = props;
|
const { field, cell, tableStyles, cellProps } = props;
|
||||||
|
|
||||||
const displayValue = field.display!(cell.value);
|
const displayValue = field.display!(cell.value);
|
||||||
|
|
||||||
@ -22,33 +22,9 @@ export const DefaultCell: FC<TableCellProps> = (props) => {
|
|||||||
const cellStyle = getCellStyle(tableStyles, field, displayValue);
|
const cellStyle = getCellStyle(tableStyles, field, displayValue);
|
||||||
const showFilters = field.config.filterable;
|
const showFilters = field.config.filterable;
|
||||||
|
|
||||||
let link: LinkModel<any> | undefined;
|
|
||||||
let onClick: MouseEventHandler<HTMLAnchorElement> | undefined;
|
|
||||||
|
|
||||||
if (field.getLinks) {
|
|
||||||
link = field.getLinks({
|
|
||||||
valueRowIndex: row.index,
|
|
||||||
})[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link && link.onClick) {
|
|
||||||
onClick = (event) => {
|
|
||||||
// Allow opening in new tab
|
|
||||||
if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link!.onClick) {
|
|
||||||
event.preventDefault();
|
|
||||||
link!.onClick(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...cellProps} className={cellStyle}>
|
<div {...cellProps} className={cellStyle}>
|
||||||
{!link && <div className={tableStyles.cellText}>{value}</div>}
|
<div className={tableStyles.cellText}>{value}</div>
|
||||||
{link && (
|
|
||||||
<a href={link.href} onClick={onClick} target={link.target} title={link.title} className={tableStyles.cellLink}>
|
|
||||||
{value}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
{showFilters && cell.value !== undefined && <FilterActions {...props} />}
|
{showFilters && cell.value !== undefined && <FilterActions {...props} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -166,8 +166,8 @@ export const Table: FC<Props> = memo((props: Props) => {
|
|||||||
const { fields } = data;
|
const { fields } = data;
|
||||||
|
|
||||||
const RenderRow = React.useCallback(
|
const RenderRow = React.useCallback(
|
||||||
({ index, style }) => {
|
({ index: rowIndex, style }) => {
|
||||||
const row = rows[index];
|
const row = rows[rowIndex];
|
||||||
prepareRow(row);
|
prepareRow(row);
|
||||||
return (
|
return (
|
||||||
<div {...row.getRowProps({ style })} className={tableStyles.row}>
|
<div {...row.getRowProps({ style })} className={tableStyles.row}>
|
||||||
@ -180,6 +180,7 @@ export const Table: FC<Props> = memo((props: Props) => {
|
|||||||
onCellFilterAdded={onCellFilterAdded}
|
onCellFilterAdded={onCellFilterAdded}
|
||||||
columnIndex={index}
|
columnIndex={index}
|
||||||
columnCount={row.cells.length}
|
columnCount={row.cells.length}
|
||||||
|
rowIndex={rowIndex}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { FC } from 'react';
|
import React, { FC, MouseEventHandler } from 'react';
|
||||||
import { Cell } from 'react-table';
|
import { Cell } from 'react-table';
|
||||||
import { Field } from '@grafana/data';
|
import { Field, LinkModel } from '@grafana/data';
|
||||||
import { TableFilterActionCallback } from './types';
|
import { TableFilterActionCallback } from './types';
|
||||||
import { TableStyles } from './styles';
|
import { TableStyles } from './styles';
|
||||||
|
|
||||||
@ -11,9 +11,18 @@ export interface Props {
|
|||||||
onCellFilterAdded?: TableFilterActionCallback;
|
onCellFilterAdded?: TableFilterActionCallback;
|
||||||
columnIndex: number;
|
columnIndex: number;
|
||||||
columnCount: number;
|
columnCount: number;
|
||||||
|
rowIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TableCell: FC<Props> = ({ cell, field, tableStyles, onCellFilterAdded, columnIndex, columnCount }) => {
|
export const TableCell: FC<Props> = ({
|
||||||
|
cell,
|
||||||
|
field,
|
||||||
|
tableStyles,
|
||||||
|
onCellFilterAdded,
|
||||||
|
columnIndex,
|
||||||
|
columnCount,
|
||||||
|
rowIndex,
|
||||||
|
}) => {
|
||||||
const cellProps = cell.getCellProps();
|
const cellProps = cell.getCellProps();
|
||||||
|
|
||||||
if (!field.display) {
|
if (!field.display) {
|
||||||
@ -32,15 +41,33 @@ export const TableCell: FC<Props> = ({ cell, field, tableStyles, onCellFilterAdd
|
|||||||
innerWidth -= tableStyles.lastChildExtraPadding;
|
innerWidth -= tableStyles.lastChildExtraPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const link: LinkModel | undefined = field.getLinks?.({
|
||||||
<>
|
valueRowIndex: rowIndex,
|
||||||
{cell.render('Cell', {
|
})[0];
|
||||||
field,
|
|
||||||
tableStyles,
|
let onClick: MouseEventHandler<HTMLAnchorElement> | undefined;
|
||||||
onCellFilterAdded,
|
if (link?.onClick) {
|
||||||
cellProps,
|
onClick = (event) => {
|
||||||
innerWidth,
|
// Allow opening in new tab
|
||||||
})}
|
if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link!.onClick) {
|
||||||
</>
|
event.preventDefault();
|
||||||
|
link!.onClick(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderedCell = cell.render('Cell', {
|
||||||
|
field,
|
||||||
|
tableStyles,
|
||||||
|
onCellFilterAdded,
|
||||||
|
cellProps,
|
||||||
|
innerWidth,
|
||||||
|
});
|
||||||
|
return link ? (
|
||||||
|
<a href={link.href} onClick={onClick} target={link.target} title={link.title} className={tableStyles.cellLink}>
|
||||||
|
{renderedCell}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<>{renderedCell}</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -90,7 +90,6 @@ export const getTableStyles = stylesFactory((theme: GrafanaTheme) => {
|
|||||||
`,
|
`,
|
||||||
cellContainer: buildCellContainerStyle(),
|
cellContainer: buildCellContainerStyle(),
|
||||||
cellText: css`
|
cellText: css`
|
||||||
cursor: text;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
|
Loading…
Reference in New Issue
Block a user