grafana/public/app/plugins/panel/table/TablePanel.tsx

133 lines
3.5 KiB
TypeScript
Raw Normal View History

2019-03-08 08:52:20 +08:00
import React, { Component } from 'react';
2019-03-06 10:17:44 +08:00
import { Table, Select } from '@grafana/ui';
import { FieldMatcherID, PanelProps, DataFrame, SelectableValue, getFrameDisplayName } from '@grafana/data';
2019-03-07 02:54:47 +08:00
import { Options } from './types';
import { css } from 'emotion';
import { config } from 'app/core/config';
import { TableSortByFieldState } from '@grafana/ui/src/components/Table/types';
2019-03-07 02:54:47 +08:00
2019-03-06 08:07:46 +08:00
interface Props extends PanelProps<Options> {}
2019-03-08 08:52:20 +08:00
export class TablePanel extends Component<Props> {
2019-03-07 02:10:04 +08:00
constructor(props: Props) {
super(props);
2019-03-06 10:17:44 +08:00
}
onColumnResize = (fieldDisplayName: string, width: number) => {
const { fieldConfig } = this.props;
const { overrides } = fieldConfig;
const matcherId = FieldMatcherID.byName;
const propId = 'custom.width';
// look for existing override
const override = overrides.find(o => o.matcher.id === matcherId && o.matcher.options === fieldDisplayName);
if (override) {
// look for existing property
const property = override.properties.find(prop => prop.id === propId);
if (property) {
property.value = width;
} else {
override.properties.push({ id: propId, value: width });
}
} else {
overrides.push({
matcher: { id: matcherId, options: fieldDisplayName },
properties: [{ id: propId, value: width }],
});
}
this.props.onFieldConfigChange({
...fieldConfig,
overrides,
});
};
onSortByChange = (sortBy: TableSortByFieldState[]) => {
this.props.onOptionsChange({
...this.props.options,
sortBy,
});
};
onChangeTableSelection = (val: SelectableValue<number>) => {
this.props.onOptionsChange({
...this.props.options,
frameIndex: val.value || 0,
});
// Force a redraw -- but no need to re-query
this.forceUpdate();
};
renderTable(frame: DataFrame, width: number, height: number) {
const { options } = this.props;
return (
<Table
height={height}
width={width}
data={frame}
noHeader={!options.showHeader}
resizable={true}
initialSortBy={options.sortBy}
onSortByChange={this.onSortByChange}
onColumnResize={this.onColumnResize}
/>
);
}
getCurrentFrameIndex() {
const { data, options } = this.props;
const count = data.series?.length;
return options.frameIndex > 0 && options.frameIndex < count ? options.frameIndex : 0;
}
2019-03-06 10:17:44 +08:00
render() {
const { data, height, width } = this.props;
2019-03-07 02:10:04 +08:00
const count = data.series?.length;
if (!count || count < 1) {
return <div>No data</div>;
2019-03-06 08:07:46 +08:00
}
if (count > 1) {
const inputHeight = config.theme.spacing.formInputHeight;
const padding = 8 * 2;
const currentIndex = this.getCurrentFrameIndex();
const names = data.series.map((frame, index) => {
return {
label: getFrameDisplayName(frame),
value: index,
};
});
return (
<div className={tableStyles.wrapper}>
{this.renderTable(data.series[currentIndex], width, height - inputHeight - padding)}
<div className={tableStyles.selectWrapper}>
<Select options={names} value={names[currentIndex]} onChange={this.onChangeTableSelection} />
</div>
</div>
);
}
return this.renderTable(data.series[0], width, height - 12);
2019-03-06 08:07:46 +08:00
}
}
const tableStyles = {
wrapper: css`
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
`,
selectWrapper: css`
padding: 8px;
`,
};