mirror of https://github.com/grafana/grafana
parent
ca5d7c3510
commit
e1324289c8
@ -1,187 +0,0 @@ |
|||||||
// Libraries
|
|
||||||
import React, { Component, ReactNode } from 'react'; |
|
||||||
import { |
|
||||||
Table, |
|
||||||
SortDirectionType, |
|
||||||
SortIndicator, |
|
||||||
Column, |
|
||||||
TableHeaderProps, |
|
||||||
TableCellProps, |
|
||||||
Index, |
|
||||||
} from 'react-virtualized'; |
|
||||||
import { Themeable } from '../../types/theme'; |
|
||||||
|
|
||||||
import { sortTableData } from '../../utils/processTimeSeries'; |
|
||||||
|
|
||||||
// Types
|
|
||||||
import { TableData, InterpolateFunction } from '../../types/index'; |
|
||||||
import { TableRenderer } from './renderer'; |
|
||||||
|
|
||||||
// Made to match the existing (untyped) settings in the angular table
|
|
||||||
export interface ColumnStyle { |
|
||||||
pattern?: string; |
|
||||||
|
|
||||||
alias?: string; |
|
||||||
colorMode?: string; |
|
||||||
colors?: any[]; |
|
||||||
decimals?: number; |
|
||||||
thresholds?: any[]; |
|
||||||
type?: 'date' | 'number' | 'string' | 'hidden'; |
|
||||||
unit?: string; |
|
||||||
dateFormat?: string; |
|
||||||
sanitize?: boolean; |
|
||||||
mappingType?: any; |
|
||||||
valueMaps?: any; |
|
||||||
rangeMaps?: any; |
|
||||||
|
|
||||||
link?: any; |
|
||||||
linkUrl?: any; |
|
||||||
linkTooltip?: any; |
|
||||||
linkTargetBlank?: boolean; |
|
||||||
|
|
||||||
preserveFormat?: boolean; |
|
||||||
} |
|
||||||
|
|
||||||
interface Props extends Themeable { |
|
||||||
data?: TableData; |
|
||||||
showHeader: boolean; |
|
||||||
styles: ColumnStyle[]; |
|
||||||
replaceVariables: InterpolateFunction; |
|
||||||
width: number; |
|
||||||
height: number; |
|
||||||
} |
|
||||||
|
|
||||||
interface State { |
|
||||||
sortBy?: number; |
|
||||||
sortDirection?: SortDirectionType; |
|
||||||
data?: TableData; |
|
||||||
} |
|
||||||
|
|
||||||
export class DataTable extends Component<Props, State> { |
|
||||||
renderer: TableRenderer; |
|
||||||
|
|
||||||
static defaultProps = { |
|
||||||
showHeader: true, |
|
||||||
}; |
|
||||||
|
|
||||||
constructor(props: Props) { |
|
||||||
super(props); |
|
||||||
|
|
||||||
this.state = { |
|
||||||
data: props.data, |
|
||||||
}; |
|
||||||
|
|
||||||
this.renderer = this.createRenderer(); |
|
||||||
} |
|
||||||
|
|
||||||
componentDidUpdate(prevProps: Props, prevState: State) { |
|
||||||
const { data, styles } = this.props; |
|
||||||
const { sortBy, sortDirection } = this.state; |
|
||||||
const dataChanged = data !== prevProps.data; |
|
||||||
|
|
||||||
// Update the renderer if options change
|
|
||||||
if (dataChanged || styles !== prevProps.styles) { |
|
||||||
this.renderer = this.createRenderer(); |
|
||||||
} |
|
||||||
|
|
||||||
// Update the data when data or sort changes
|
|
||||||
if (dataChanged || sortBy !== prevState.sortBy || sortDirection !== prevState.sortDirection) { |
|
||||||
const sorted = data ? sortTableData(data, sortBy, sortDirection === 'DESC') : data; |
|
||||||
this.setState({ data: sorted }); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// styles: ColumnStyle[],
|
|
||||||
// schema: Column[],
|
|
||||||
// rowGetter: (info: Index) => any[], // matches the table rowGetter
|
|
||||||
// replaceVariables: InterpolateFunction,
|
|
||||||
// isUTC?: boolean, // TODO? get UTC from props?
|
|
||||||
// theme?: GrafanaThemeType | undefined,
|
|
||||||
|
|
||||||
createRenderer(): TableRenderer { |
|
||||||
const { styles, replaceVariables, theme } = this.props; |
|
||||||
const { data } = this.state; |
|
||||||
|
|
||||||
return new TableRenderer({ |
|
||||||
styles, |
|
||||||
schema: data ? data.columns : [], |
|
||||||
rowGetter: this.rowGetter, |
|
||||||
replaceVariables, |
|
||||||
isUTC: false, |
|
||||||
theme: theme.type, |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
rowGetter = ({ index }: Index) => { |
|
||||||
return this.state.data!.rows[index]; |
|
||||||
}; |
|
||||||
|
|
||||||
doSort = (info: any) => { |
|
||||||
let dir = info.sortDirection; |
|
||||||
let sort = info.sortBy; |
|
||||||
if (sort !== this.state.sortBy) { |
|
||||||
dir = 'DESC'; |
|
||||||
} else if (dir === 'DESC') { |
|
||||||
dir = 'ASC'; |
|
||||||
} else { |
|
||||||
sort = null; |
|
||||||
} |
|
||||||
this.setState({ sortBy: sort, sortDirection: dir }); |
|
||||||
}; |
|
||||||
|
|
||||||
headerRenderer = (header: TableHeaderProps): ReactNode => { |
|
||||||
const dataKey = header.dataKey as any; // types say string, but it is number!
|
|
||||||
const { data, sortBy, sortDirection } = this.state; |
|
||||||
const col = data!.columns[dataKey]; |
|
||||||
|
|
||||||
return ( |
|
||||||
<div> |
|
||||||
{col.text} {sortBy === dataKey && <SortIndicator sortDirection={sortDirection} />} |
|
||||||
</div> |
|
||||||
); |
|
||||||
}; |
|
||||||
|
|
||||||
cellRenderer = (cell: TableCellProps) => { |
|
||||||
const { columnIndex, rowIndex } = cell; |
|
||||||
const row = this.state.data!.rows[rowIndex]; |
|
||||||
const val = row[columnIndex]; |
|
||||||
return this.renderer.renderCell(columnIndex, rowIndex, val); |
|
||||||
}; |
|
||||||
|
|
||||||
render() { |
|
||||||
const { width, height, showHeader } = this.props; |
|
||||||
const { data } = this.props; |
|
||||||
if (!data) { |
|
||||||
return <div>NO Data</div>; |
|
||||||
} |
|
||||||
return ( |
|
||||||
<Table |
|
||||||
disableHeader={!showHeader} |
|
||||||
headerHeight={30} |
|
||||||
height={height} |
|
||||||
overscanRowCount={10} |
|
||||||
rowHeight={30} |
|
||||||
rowGetter={this.rowGetter} |
|
||||||
rowCount={data.rows.length} |
|
||||||
sort={this.doSort} |
|
||||||
width={width} |
|
||||||
> |
|
||||||
{data.columns.map((col, index) => { |
|
||||||
return ( |
|
||||||
<Column |
|
||||||
key={index} |
|
||||||
dataKey={index} |
|
||||||
headerRenderer={this.headerRenderer} |
|
||||||
cellRenderer={this.cellRenderer} |
|
||||||
width={150} |
|
||||||
minWidth={50} |
|
||||||
flexGrow={1} |
|
||||||
/> |
|
||||||
); |
|
||||||
})} |
|
||||||
</Table> |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default DataTable; |
|
Loading…
Reference in new issue