mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
TablePanel: Adding sort order persistance (#24705)
* TablePanel: Adding sort order persistance * adds panel test dashboard for table panel
This commit is contained in:
parent
6b29c11776
commit
b709f6ad71
602
devenv/dev-dashboards/panel-table/table_tests_new.json
Normal file
602
devenv/dev-dashboards/panel-table/table_tests_new.json
Normal file
@ -0,0 +1,602 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 7,
|
||||
"title": "Cell styles",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": "center",
|
||||
"displayMode": "color-background"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 60
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "degree"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Max"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 84
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Last"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 78
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Mean"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 74
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Field"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.align",
|
||||
"value": "left"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 16,
|
||||
"w": 7,
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"showHeader": true,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": true,
|
||||
"displayName": "Last"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 15,
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Colored background",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "reduce",
|
||||
"options": {
|
||||
"reducers": ["max", "mean", "last"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": null
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "orange",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Value"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.displayMode",
|
||||
"value": "gradient-gauge"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Info"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 92
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Min"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 76
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Max"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 89
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Time"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 165
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 16,
|
||||
"w": 8,
|
||||
"x": 7,
|
||||
"y": 1
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"showHeader": true,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": false,
|
||||
"displayName": "Min"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk_table",
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Bar gauge cells",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Time": true
|
||||
},
|
||||
"indexByName": {
|
||||
"Info": 1,
|
||||
"Max": 3,
|
||||
"Min": 2,
|
||||
"Time": 0,
|
||||
"Value": 4
|
||||
},
|
||||
"renameByName": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": null
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"value": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Value"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.displayMode",
|
||||
"value": "lcd-gauge"
|
||||
},
|
||||
{
|
||||
"id": "custom.align",
|
||||
"value": "center"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 16,
|
||||
"w": 9,
|
||||
"x": 15,
|
||||
"y": 1
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"showHeader": true,
|
||||
"sortBy": []
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk_table",
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Retro LCD cell",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Info": false,
|
||||
"Max": true,
|
||||
"Min": true,
|
||||
"Time": false
|
||||
},
|
||||
"indexByName": {
|
||||
"Info": 1,
|
||||
"Max": 3,
|
||||
"Min": 2,
|
||||
"Time": 0,
|
||||
"Value": 4
|
||||
},
|
||||
"renameByName": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 17
|
||||
},
|
||||
"id": 9,
|
||||
"panels": [],
|
||||
"title": "Data links",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": "center",
|
||||
"displayMode": "color-text"
|
||||
},
|
||||
"decimals": 2,
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 50
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "percent"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Time"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.align",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "{name=\"S1\", server=\"A\"}"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "links",
|
||||
"value": [
|
||||
{
|
||||
"title": "Details",
|
||||
"url": "http://detail?serverLabel=${__field.labels.server}&valueNumeric=${__value.numeric}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
},
|
||||
"id": 3,
|
||||
"maxDataPoints": "10",
|
||||
"options": {
|
||||
"showHeader": true
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "S1",
|
||||
"labels": "server=A",
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 1,
|
||||
"stringInput": ""
|
||||
},
|
||||
{
|
||||
"alias": "S2",
|
||||
"labels": "server=B",
|
||||
"refId": "B",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 1,
|
||||
"stringInput": ""
|
||||
},
|
||||
{
|
||||
"alias": "S3",
|
||||
"labels": "server=C",
|
||||
"refId": "C",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 1,
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Data link with labels and numeric value",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "seriesToColumns",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": "center",
|
||||
"displayMode": "auto"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 60
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "degree"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 5,
|
||||
"x": 12,
|
||||
"y": 18
|
||||
},
|
||||
"id": 10,
|
||||
"options": {
|
||||
"showHeader": false,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": true,
|
||||
"displayName": "Last"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk_table",
|
||||
"seriesCount": 5,
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "No header",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Min": true,
|
||||
"Time": true,
|
||||
"Value": true
|
||||
},
|
||||
"indexByName": {
|
||||
"Info": 2,
|
||||
"Max": 4,
|
||||
"Min": 3,
|
||||
"Time": 0,
|
||||
"Value": 1
|
||||
},
|
||||
"renameByName": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 25,
|
||||
"style": "dark",
|
||||
"tags": ["gdev", "panel-tests"],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - React Table",
|
||||
"uid": "U_bZIMRMk",
|
||||
"version": 17
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React, { FC, memo, useCallback, useMemo } from 'react';
|
||||
import { DataFrame, Field } from '@grafana/data';
|
||||
import { DataFrame, Field, getFieldDisplayName } from '@grafana/data';
|
||||
import {
|
||||
Cell,
|
||||
Column,
|
||||
@ -14,7 +14,12 @@ import {
|
||||
import { FixedSizeList } from 'react-window';
|
||||
import { getColumns, getTextAlign } from './utils';
|
||||
import { useTheme } from '../../themes';
|
||||
import { TableColumnResizeActionCallback, TableFilterActionCallback, TableSortByActionCallback } from './types';
|
||||
import {
|
||||
TableColumnResizeActionCallback,
|
||||
TableFilterActionCallback,
|
||||
TableSortByActionCallback,
|
||||
TableSortByFieldState,
|
||||
} from './types';
|
||||
import { getTableStyles, TableStyles } from './styles';
|
||||
import { TableCell } from './TableCell';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
@ -30,9 +35,10 @@ export interface Props {
|
||||
columnMinWidth?: number;
|
||||
noHeader?: boolean;
|
||||
resizable?: boolean;
|
||||
initialSortBy?: TableSortByFieldState[];
|
||||
onCellClick?: TableFilterActionCallback;
|
||||
onColumnResize?: TableColumnResizeActionCallback;
|
||||
onSortBy?: TableSortByActionCallback;
|
||||
onSortByChange?: TableSortByActionCallback;
|
||||
}
|
||||
|
||||
interface ReactTableInternalState extends UseResizeColumnsState<{}>, UseSortByState<{}> {}
|
||||
@ -43,25 +49,66 @@ function useTableStateReducer(props: Props) {
|
||||
switch (action.type) {
|
||||
case 'columnDoneResizing':
|
||||
if (props.onColumnResize) {
|
||||
const { data } = props;
|
||||
const info = (newState.columnResizing.headerIdWidths as any)[0];
|
||||
const columnIdString = info[0];
|
||||
const fieldIndex = parseInt(columnIdString, 10);
|
||||
const width = Math.round(newState.columnResizing.columnWidths[columnIdString] as number);
|
||||
props.onColumnResize(fieldIndex, width);
|
||||
|
||||
const field = data.fields[fieldIndex];
|
||||
if (!field) {
|
||||
return newState;
|
||||
}
|
||||
|
||||
const fieldDisplayName = getFieldDisplayName(field, data);
|
||||
props.onColumnResize(fieldDisplayName, width);
|
||||
}
|
||||
case 'toggleSortBy':
|
||||
if (props.onSortBy) {
|
||||
// todo call callback and persist
|
||||
if (props.onSortByChange) {
|
||||
const { data } = props;
|
||||
const sortByFields: TableSortByFieldState[] = [];
|
||||
|
||||
for (const sortItem of newState.sortBy) {
|
||||
const field = data.fields[parseInt(sortItem.id, 10)];
|
||||
if (!field) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sortByFields.push({
|
||||
displayName: getFieldDisplayName(field, data),
|
||||
desc: sortItem.desc,
|
||||
});
|
||||
}
|
||||
|
||||
props.onSortByChange(sortByFields);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return newState;
|
||||
},
|
||||
[props.onColumnResize]
|
||||
[props.onColumnResize, props.onSortByChange, props.data]
|
||||
);
|
||||
}
|
||||
|
||||
function getInitialState(props: Props, columns: Column[]): Partial<ReactTableInternalState> {
|
||||
const state: Partial<ReactTableInternalState> = {};
|
||||
|
||||
if (props.initialSortBy) {
|
||||
state.sortBy = [];
|
||||
|
||||
for (const sortBy of props.initialSortBy) {
|
||||
for (const col of columns) {
|
||||
if (col.Header === sortBy.displayName) {
|
||||
state.sortBy.push({ id: col.id as string, desc: sortBy.desc });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
export const Table: FC<Props> = memo((props: Props) => {
|
||||
const { data, height, onCellClick, width, columnMinWidth = COLUMN_MIN_WIDTH, noHeader, resizable = true } = props;
|
||||
const theme = useTheme();
|
||||
@ -91,10 +138,7 @@ export const Table: FC<Props> = memo((props: Props) => {
|
||||
data: memoizedData,
|
||||
disableResizing: !resizable,
|
||||
stateReducer: stateReducer,
|
||||
// this is how you set initial sort by state
|
||||
// initialState: {
|
||||
// sortBy: [{ id: '2', desc: true }],
|
||||
// },
|
||||
initialState: getInitialState(props, memoizedColumns),
|
||||
}),
|
||||
[memoizedColumns, memoizedData, stateReducer, resizable]
|
||||
);
|
||||
|
@ -26,11 +26,11 @@ export interface TableRow {
|
||||
}
|
||||
|
||||
export type TableFilterActionCallback = (key: string, value: string) => void;
|
||||
export type TableColumnResizeActionCallback = (fieldIndex: number, width: number) => void;
|
||||
export type TableColumnResizeActionCallback = (fieldDisplayName: string, width: number) => void;
|
||||
export type TableSortByActionCallback = (state: TableSortByFieldState[]) => void;
|
||||
|
||||
export interface TableSortByFieldState {
|
||||
fieldIndex: number;
|
||||
displayName: string;
|
||||
desc?: boolean;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ export { ModalsProvider, ModalRoot, ModalsController } from './Modal/ModalsConte
|
||||
export { SetInterval } from './SetInterval/SetInterval';
|
||||
|
||||
export { Table } from './Table/Table';
|
||||
export { TableCellDisplayMode } from './Table/types';
|
||||
export { TableCellDisplayMode, TableSortByFieldState } from './Table/types';
|
||||
export { TableInputCSV } from './TableInputCSV/TableInputCSV';
|
||||
export { TabsBar } from './Tabs/TabsBar';
|
||||
export { Tab } from './Tabs/Tab';
|
||||
|
@ -1,17 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Table, Select } from '@grafana/ui';
|
||||
import {
|
||||
FieldMatcherID,
|
||||
PanelProps,
|
||||
DataFrame,
|
||||
SelectableValue,
|
||||
getFrameDisplayName,
|
||||
getFieldDisplayName,
|
||||
} from '@grafana/data';
|
||||
import { FieldMatcherID, PanelProps, DataFrame, SelectableValue, getFrameDisplayName } from '@grafana/data';
|
||||
import { Options } from './types';
|
||||
import { css } from 'emotion';
|
||||
import { config } from 'app/core/config';
|
||||
import { TableSortByFieldState } from '@grafana/ui/src/components/Table/types';
|
||||
|
||||
interface Props extends PanelProps<Options> {}
|
||||
|
||||
@ -20,21 +14,10 @@ export class TablePanel extends Component<Props> {
|
||||
super(props);
|
||||
}
|
||||
|
||||
onColumnResize = (fieldIndex: number, width: number) => {
|
||||
const { fieldConfig, data } = this.props;
|
||||
onColumnResize = (fieldDisplayName: string, width: number) => {
|
||||
const { fieldConfig } = this.props;
|
||||
const { overrides } = fieldConfig;
|
||||
const frame = data.series[this.getCurrentFrameIndex()];
|
||||
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
const field = frame.fields[fieldIndex];
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fieldDisplayName = getFieldDisplayName(field, frame, data.series);
|
||||
const matcherId = FieldMatcherID.byName;
|
||||
const propId = 'custom.width';
|
||||
|
||||
@ -62,6 +45,13 @@ export class TablePanel extends Component<Props> {
|
||||
});
|
||||
};
|
||||
|
||||
onSortByChange = (sortBy: TableSortByFieldState[]) => {
|
||||
this.props.onOptionsChange({
|
||||
...this.props.options,
|
||||
sortBy,
|
||||
});
|
||||
};
|
||||
|
||||
onChangeTableSelection = (val: SelectableValue<number>) => {
|
||||
this.props.onOptionsChange({
|
||||
...this.props.options,
|
||||
@ -82,6 +72,8 @@ export class TablePanel extends Component<Props> {
|
||||
data={frame}
|
||||
noHeader={!options.showHeader}
|
||||
resizable={true}
|
||||
initialSortBy={options.sortBy}
|
||||
onSortByChange={this.onSortByChange}
|
||||
onColumnResize={this.onColumnResize}
|
||||
/>
|
||||
);
|
||||
|
@ -1,6 +1,14 @@
|
||||
import { TableSortByFieldState } from '@grafana/ui';
|
||||
|
||||
export interface Options {
|
||||
frameIndex: number;
|
||||
showHeader: boolean;
|
||||
sortBy?: TableSortByFieldState[];
|
||||
}
|
||||
|
||||
export interface TableSortBy {
|
||||
displayName: string;
|
||||
desc: boolean;
|
||||
}
|
||||
|
||||
export interface CustomFieldConfig {
|
||||
|
Loading…
Reference in New Issue
Block a user