Merge branch 'adela/table-ng_datalinks_support' into adela/table-ng_actions_support1

pull/100790/head
Adela Almasan 5 months ago
commit 45e06ec36e
  1. 3
      .betterer.results
  2. 1
      packages/grafana-ui/src/components/Table/Cells/DataLinksCell.tsx
  3. 50
      packages/grafana-ui/src/components/Table/TableNG/Cells/DataLinksCell.tsx
  4. 5
      packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellNG.tsx
  5. 23
      packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx
  6. 15
      packages/grafana-ui/src/components/Table/TableNG/utils.ts

@ -639,9 +639,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-ui/src/components/Table/Cells/DataLinksCell.tsx:5381": [
[0, 0, 0, "There should be no empty line within import group", "0"]
],
"packages/grafana-ui/src/components/Table/Cells/TableCell.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],

@ -1,5 +1,4 @@
import { getCellLinks } from '../../../utils';
import { TableCellProps } from '../types';
export const DataLinksCell = (props: TableCellProps) => {

@ -0,0 +1,50 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../../../themes';
import { CellNGProps } from '../types';
import { getCellLinks } from '../utils';
export const DataLinksCell = (props: CellNGProps) => {
const { field, rowIdx } = props;
const styles = useStyles2(getStyles);
const links = getCellLinks(field, rowIdx!);
return (
<div>
{links &&
links.map((link, idx) => {
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<span key={idx} className={styles.linkCell} onClick={link.onClick}>
<a href={link.href} target={link.target}>
{link.title}
</a>
</span>
);
})}
</div>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
linkCell: css({
cursor: 'pointer',
overflow: 'hidden',
textOverflow: 'ellipsis',
userSelect: 'text',
whiteSpace: 'nowrap',
color: theme.colors.text.link,
fontWeight: theme.typography.fontWeightMedium,
paddingRight: theme.spacing(1.5),
a: {
color: theme.colors.text.link,
},
'&:hover': {
textDecoration: 'underline',
color: theme.colors.text.link,
},
}),
});

@ -13,6 +13,7 @@ import { getCellColors } from '../utils';
import AutoCell from './AutoCell';
import { BarGaugeCell } from './BarGaugeCell';
import { DataLinksCell } from './DataLinksCell';
import { ImageCell } from './ImageCell';
import { JSONCell } from './JSONCell';
import { SparklineCell } from './SparklineCell';
@ -22,6 +23,7 @@ import { SparklineCell } from './SparklineCell';
// fieldDisplay: any?
// }
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
export function TableCellNG(props: any) {
const {
field,
@ -117,6 +119,9 @@ export function TableCellNG(props: any) {
case TableCellDisplayMode.JSONView:
cell = <JSONCell value={value} justifyContent={justifyContent} field={field} rowIdx={rowIdx} actions={actions} />;
break;
case TableCellDisplayMode.DataLinks:
cell = <DataLinksCell value={value} field={field} theme={theme} justifyContent={justifyContent} />;
break;
case TableCellDisplayMode.Auto:
default:
cell = (

@ -51,6 +51,13 @@ export type FilterType = {
};
};
/**
* getIsNestedTable is a helper function that takes a DataFrame and returns a
* boolean value based on the presence of nested frames
*/
const getIsNestedTable = (dataFrame: DataFrame): boolean =>
dataFrame.fields.some(({ type }) => type === FieldType.nestedFrames);
export function TableNG(props: TableNGProps) {
const {
height,
@ -158,6 +165,7 @@ export function TableNG(props: TableNGProps) {
// setSortColumns is still used to trigger re-render
const sortColumnsRef = useRef(sortColumns);
const [expandedRows, setExpandedRows] = useState<number[]>([]);
const [isNestedTable, setIsNestedTable] = useState(false);
function getDefaultRowHeight(): number {
const bodyFontSize = theme.typography.fontSize;
@ -230,12 +238,10 @@ export function TableNG(props: TableNGProps) {
const mapFrameToDataGrid = (main: DataFrame, calcsRef: React.MutableRefObject<string[]>, subTable?: boolean) => {
const columns: TableColumn[] = [];
// Check for nestedFrames
const nestedDataField = main.fields.find((f) => f.type === FieldType.nestedFrames);
const hasNestedData = nestedDataField !== undefined;
const hasNestedFrames = getIsNestedTable(main);
// If nested frames, add expansion control column
if (hasNestedData) {
if (hasNestedFrames) {
const expanderField: Field = {
name: '',
type: FieldType.other,
@ -546,9 +552,14 @@ export function TableNG(props: TableNGProps) {
const columns = useMemo(
() => mapFrameToDataGrid(props.data, calcsRef),
[props.data, calcsRef, filter, expandedRows, footerOptions] // eslint-disable-line react-hooks/exhaustive-deps
[props.data, calcsRef, filter, expandedRows, expandedRows.length, footerOptions] // eslint-disable-line react-hooks/exhaustive-deps
);
useEffect(() => {
const hasNestedFrames = getIsNestedTable(props.data);
setIsNestedTable(hasNestedFrames);
}, [props.data]);
// This effect needed to set header cells refs before row height calculation
useLayoutEffect(() => {
setReadyForRowHeightCalc(Object.keys(headerCellRefs.current).length > 0);
@ -603,7 +614,7 @@ export function TableNG(props: TableNGProps) {
sortable: true,
resizable: true,
}}
rowHeight={textWrap ? calculateRowHeight : defaultRowHeight}
rowHeight={textWrap || isNestedTable ? calculateRowHeight : defaultRowHeight}
// TODO: This doesn't follow current table behavior
style={{ width, height: height - (enablePagination ? paginationHeight : 0) }}
renderers={{ renderRow: myRowRenderer }}

@ -216,23 +216,14 @@ export function getCellColors(
return { textColor, bgColor, bgHoverColor };
}
export const getLinks = (field: Field, rowIdx: number) => {
if (field.getLinks) {
return field.getLinks({ valueRowIndex: rowIdx });
}
return [];
};
/**
* @internal
* TODO: unify with the existing getCellLinks
*/
export const getCellLinks = (field: Field, rowIndex: number) => {
export const getCellLinks = (field: Field, rowIdx: number) => {
let links: Array<LinkModel<unknown>> | undefined;
if (field.getLinks) {
links = field.getLinks({
valueRowIndex: rowIndex,
valueRowIndex: rowIdx,
});
}
@ -250,7 +241,7 @@ export const getCellLinks = (field: Field, rowIndex: number) => {
event.preventDefault();
origOnClick!(event, {
field,
rowIndex: rowIndex,
rowIndex: rowIdx,
});
}
};

Loading…
Cancel
Save