2019-01-13 16:10:23 -06:00
|
|
|
import React, { PureComponent } from 'react';
|
2021-06-24 01:21:19 -05:00
|
|
|
import { connect, ConnectedProps } from 'react-redux';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
2023-08-10 06:33:46 -05:00
|
|
|
import { applyFieldOverrides, TimeZone, SplitOpen, DataFrame, LoadingState, FieldType } from '@grafana/data';
|
2023-09-05 06:10:01 -05:00
|
|
|
import { getTemplateSrv } from '@grafana/runtime';
|
2023-04-12 11:58:08 -05:00
|
|
|
import { Table, AdHocFilterItem, PanelChrome } from '@grafana/ui';
|
2019-12-27 02:11:16 -06:00
|
|
|
import { config } from 'app/core/config';
|
2023-09-28 04:51:37 -05:00
|
|
|
import { t } from 'app/core/internationalization';
|
2023-08-10 06:33:46 -05:00
|
|
|
import {
|
|
|
|
hasDeprecatedParentRowIndex,
|
|
|
|
migrateFromParentRowIndexToNestedFrames,
|
|
|
|
} from 'app/plugins/panel/table/migrations';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { StoreState } from 'app/types';
|
2023-06-21 04:06:28 -05:00
|
|
|
import { ExploreItemState } from 'app/types/explore';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
2023-05-23 08:42:38 -05:00
|
|
|
import { MetaInfoText } from '../MetaInfoText';
|
2023-06-20 10:38:05 -05:00
|
|
|
import { selectIsWaitingForData } from '../state/query';
|
2023-07-31 07:10:03 -05:00
|
|
|
import { exploreDataLinkPostProcessorFactory } from '../utils/links';
|
2019-01-13 16:10:23 -06:00
|
|
|
|
|
|
|
interface TableContainerProps {
|
2020-08-28 11:59:56 -05:00
|
|
|
ariaLabel?: string;
|
2023-06-21 04:06:28 -05:00
|
|
|
exploreId: string;
|
2019-12-18 01:38:50 -06:00
|
|
|
width: number;
|
2021-12-02 05:07:23 -06:00
|
|
|
timeZone: TimeZone;
|
2023-01-19 07:03:13 -06:00
|
|
|
onCellFilterAdded?: (filter: AdHocFilterItem) => void;
|
2022-11-02 05:22:09 -05:00
|
|
|
splitOpenFn: SplitOpen;
|
2019-01-13 16:10:23 -06:00
|
|
|
}
|
|
|
|
|
2021-06-24 01:21:19 -05:00
|
|
|
function mapStateToProps(state: StoreState, { exploreId }: TableContainerProps) {
|
|
|
|
const explore = state.explore;
|
2023-05-03 10:45:11 -05:00
|
|
|
const item: ExploreItemState = explore.panes[exploreId]!;
|
2023-06-20 10:38:05 -05:00
|
|
|
const { tableResult, range } = item;
|
|
|
|
const loadingInState = selectIsWaitingForData(exploreId);
|
2021-06-24 01:21:19 -05:00
|
|
|
const loading = tableResult && tableResult.length > 0 ? false : loadingInState;
|
|
|
|
return { loading, tableResult, range };
|
|
|
|
}
|
|
|
|
|
2022-11-02 05:22:09 -05:00
|
|
|
const connector = connect(mapStateToProps, {});
|
2021-06-24 01:21:19 -05:00
|
|
|
|
|
|
|
type Props = TableContainerProps & ConnectedProps<typeof connector>;
|
|
|
|
|
|
|
|
export class TableContainer extends PureComponent<Props> {
|
2023-08-10 06:33:46 -05:00
|
|
|
hasSubFrames = (data: DataFrame) => data.fields.some((f) => f.type === FieldType.nestedFrames);
|
2022-11-23 11:49:32 -06:00
|
|
|
|
2023-08-10 06:33:46 -05:00
|
|
|
getTableHeight(rowCount: number, hasSubFrames: boolean) {
|
2023-07-13 06:44:42 -05:00
|
|
|
if (rowCount === 0) {
|
2019-12-18 01:38:50 -06:00
|
|
|
return 200;
|
|
|
|
}
|
2023-07-13 06:44:42 -05:00
|
|
|
// tries to estimate table height, with a min of 300 and a max of 600
|
|
|
|
// if there are multiple tables, there is no min
|
2023-07-14 09:10:46 -05:00
|
|
|
return Math.min(600, Math.max(rowCount * 36, hasSubFrames ? 300 : 0) + 40 + 46);
|
2019-12-18 01:38:50 -06:00
|
|
|
}
|
|
|
|
|
2023-09-13 04:16:02 -05:00
|
|
|
getTableTitle(dataFrames: DataFrame[] | null, data: DataFrame, i: number) {
|
2023-09-28 04:51:37 -05:00
|
|
|
let name = data.name;
|
|
|
|
if (!name && (dataFrames?.length ?? 0) > 1) {
|
|
|
|
name = data.refId || `${i}`;
|
2023-09-13 04:16:02 -05:00
|
|
|
}
|
2023-09-28 04:51:37 -05:00
|
|
|
|
|
|
|
return name ? t('explore.table.title-with-name', 'Table - {{name}}', { name }) : t('explore.table.title', 'Table');
|
2023-09-13 04:16:02 -05:00
|
|
|
}
|
|
|
|
|
2019-01-13 16:10:23 -06:00
|
|
|
render() {
|
2022-11-02 05:22:09 -05:00
|
|
|
const { loading, onCellFilterAdded, tableResult, width, splitOpenFn, range, ariaLabel, timeZone } = this.props;
|
2019-01-28 06:09:51 -06:00
|
|
|
|
2023-08-10 06:33:46 -05:00
|
|
|
let dataFrames = hasDeprecatedParentRowIndex(tableResult)
|
|
|
|
? migrateFromParentRowIndexToNestedFrames(tableResult)
|
|
|
|
: tableResult;
|
2023-07-31 07:10:03 -05:00
|
|
|
const dataLinkPostProcessor = exploreDataLinkPostProcessorFactory(splitOpenFn, range);
|
|
|
|
|
2022-11-23 11:49:32 -06:00
|
|
|
if (dataFrames?.length) {
|
|
|
|
dataFrames = applyFieldOverrides({
|
|
|
|
data: dataFrames,
|
2021-12-02 05:07:23 -06:00
|
|
|
timeZone,
|
|
|
|
theme: config.theme2,
|
2023-09-05 06:10:01 -05:00
|
|
|
replaceVariables: getTemplateSrv().replace.bind(getTemplateSrv()),
|
2021-12-02 05:07:23 -06:00
|
|
|
fieldConfig: {
|
|
|
|
defaults: {},
|
|
|
|
overrides: [],
|
|
|
|
},
|
2023-07-31 07:10:03 -05:00
|
|
|
dataLinkPostProcessor,
|
2022-11-23 11:49:32 -06:00
|
|
|
});
|
2020-06-30 07:51:04 -05:00
|
|
|
}
|
|
|
|
|
2023-08-10 06:33:46 -05:00
|
|
|
const frames = dataFrames?.filter(
|
2023-07-13 06:44:42 -05:00
|
|
|
(frame: DataFrame | undefined): frame is DataFrame => !!frame && frame.length !== 0
|
|
|
|
);
|
|
|
|
|
2019-01-13 16:10:23 -06:00
|
|
|
return (
|
2023-07-13 06:44:42 -05:00
|
|
|
<>
|
2023-08-10 06:33:46 -05:00
|
|
|
{frames && frames.length === 0 && (
|
2023-09-28 04:51:37 -05:00
|
|
|
<PanelChrome title={t('explore.table.title', 'Table')} width={width} height={200}>
|
|
|
|
{() => <MetaInfoText metaItems={[{ value: t('explore.table.no-data', '0 series returned') }]} />}
|
2023-07-13 06:44:42 -05:00
|
|
|
</PanelChrome>
|
2020-01-19 21:53:59 -06:00
|
|
|
)}
|
2023-08-10 06:33:46 -05:00
|
|
|
{frames &&
|
|
|
|
frames.length > 0 &&
|
|
|
|
frames.map((data, i) => (
|
2023-07-13 06:44:42 -05:00
|
|
|
<PanelChrome
|
2023-08-10 06:33:46 -05:00
|
|
|
key={data.refId || `table-${i}`}
|
2023-09-13 04:16:02 -05:00
|
|
|
title={this.getTableTitle(dataFrames, data, i)}
|
2023-07-13 06:44:42 -05:00
|
|
|
width={width}
|
2023-08-10 06:33:46 -05:00
|
|
|
height={this.getTableHeight(data.length, this.hasSubFrames(data))}
|
2023-07-13 06:44:42 -05:00
|
|
|
loadingState={loading ? LoadingState.Loading : undefined}
|
|
|
|
>
|
|
|
|
{(innerWidth, innerHeight) => (
|
|
|
|
<Table
|
|
|
|
ariaLabel={ariaLabel}
|
2023-08-10 06:33:46 -05:00
|
|
|
data={data}
|
2023-07-13 06:44:42 -05:00
|
|
|
width={innerWidth}
|
|
|
|
height={innerHeight}
|
|
|
|
onCellFilterAdded={onCellFilterAdded}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</PanelChrome>
|
|
|
|
))}
|
|
|
|
</>
|
2019-01-13 16:10:23 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-31 05:55:05 -05:00
|
|
|
export default connector(TableContainer);
|