mirror of https://github.com/grafana/grafana
Table: Support display of multiple sub tables (#71953)
* Add nested option to DataFrame. Refactor Table to use nested dataframes for sub-tables * Use nested frames for TraceQL response * debugging * Fix cell text and table position * Update getItemSize * noHeader size * Update sub table renderer * Update table container height * Cleanup and fix RawPrometheusContainer height * Update resultTransformer and docker script * Updates to TableContainer, resultTransformer after merge * Fixes for table pagination in dashboards * Cell height and show footer enhancement/fix * Sub table links * Update RawPrometheusContainer * Remove console log * Update tests * Update storybook * Remove Tempo demo * Store nested data in single field via its values * Move nested prop into custom * Tempo demo * Add field type & update incorrect logic * Update docker compose image for Tempo * Update packages/grafana-data/src/field/fieldOverrides.ts Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com> * Simplify logic for getting nestedFrames and rendering sub tables * Update docs for table * Update nested table bg color * Lighten nested table bg color * Renames * Migrate frames using parentRowIndex and add deprecation notice * Update title * Align expander icon size between Table and interactive table * Table: Refactor out the expanded rows bits * fix spacing * Add line along left side for expanded rows * Disable hover row background when expanded --------- Co-authored-by: André Pereira <adrapereira@gmail.com> Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com> Co-authored-by: Torkel Ödegaard <torkel@grafana.com>pull/73148/head
parent
43aab615c3
commit
8c2f439cd7
@ -0,0 +1,86 @@ |
||||
import { css } from '@emotion/css'; |
||||
import React, { CSSProperties } from 'react'; |
||||
|
||||
import { DataFrame, Field, GrafanaTheme2 } from '@grafana/data'; |
||||
import { TableCellHeight } from '@grafana/schema'; |
||||
|
||||
import { useStyles2, useTheme2 } from '../../themes'; |
||||
|
||||
import { Table } from './Table'; |
||||
import { TableStyles } from './styles'; |
||||
import { EXPANDER_WIDTH } from './utils'; |
||||
|
||||
export interface Props { |
||||
nestedData: Field; |
||||
tableStyles: TableStyles; |
||||
rowIndex: number; |
||||
width: number; |
||||
cellHeight: TableCellHeight; |
||||
} |
||||
|
||||
export function ExpandedRow({ tableStyles, nestedData, rowIndex, width, cellHeight }: Props) { |
||||
const frames = nestedData.values as DataFrame[][]; |
||||
const subTables: React.ReactNode[] = []; |
||||
const theme = useTheme2(); |
||||
const styles = useStyles2(getStyles); |
||||
|
||||
let top = tableStyles.rowHeight + theme.spacing.gridSize; // initial height for row that expands above sub tables + 1 grid unit spacing
|
||||
|
||||
frames[rowIndex].forEach((nf: DataFrame, nfIndex: number) => { |
||||
const noHeader = !!nf.meta?.custom?.noHeader; |
||||
const height = tableStyles.rowHeight * (nf.length + (noHeader ? 0 : 1)); // account for the header with + 1
|
||||
|
||||
const subTable: CSSProperties = { |
||||
height: height, |
||||
paddingLeft: EXPANDER_WIDTH, |
||||
position: 'absolute', |
||||
top, |
||||
}; |
||||
|
||||
top += height + theme.spacing.gridSize; |
||||
|
||||
subTables.push( |
||||
<div style={subTable} key={`subTable_${rowIndex}_${nfIndex}`}> |
||||
<Table |
||||
data={nf} |
||||
width={width - EXPANDER_WIDTH} |
||||
height={tableStyles.rowHeight * (nf.length + 1)} |
||||
noHeader={noHeader} |
||||
cellHeight={cellHeight} |
||||
/> |
||||
</div> |
||||
); |
||||
}); |
||||
|
||||
return <div className={styles.subTables}>{subTables}</div>; |
||||
} |
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => { |
||||
return { |
||||
subTables: css({ |
||||
'&:before': { |
||||
content: '""', |
||||
position: 'absolute', |
||||
width: '1px', |
||||
top: theme.spacing(5), |
||||
left: theme.spacing(1), |
||||
bottom: theme.spacing(2), |
||||
background: theme.colors.border.medium, |
||||
}, |
||||
}), |
||||
}; |
||||
}; |
||||
|
||||
export function getExpandedRowHeight(nestedData: Field, rowIndex: number, tableStyles: TableStyles) { |
||||
const frames = nestedData.values as DataFrame[][]; |
||||
|
||||
const height = frames[rowIndex].reduce((acc: number, frame: DataFrame) => { |
||||
if (frame.length) { |
||||
const noHeader = !!frame.meta?.custom?.noHeader; |
||||
return acc + tableStyles.rowHeight * (frame.length + (noHeader ? 0 : 1)) + 8; // account for the header with + 1
|
||||
} |
||||
return acc; |
||||
}, tableStyles.rowHeight); // initial height for row that expands above sub tables
|
||||
|
||||
return height ?? tableStyles.rowHeight; |
||||
} |
Loading…
Reference in new issue