Tables: optionally show field type icon in tables (#38855)

This commit is contained in:
Ryan McKinley 2021-09-08 00:44:41 -07:00 committed by GitHub
parent ecf40f0331
commit 10ffc9a754
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 42 additions and 17 deletions

View File

@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { DataFrame, Field, FieldType, getFieldDisplayName, SelectableValue } from '@grafana/data';
import { IconName } from '../..';
import { DataFrame, Field, getFieldDisplayName, SelectableValue } from '@grafana/data';
import { getFieldTypeIcon } from '../../types';
/**
* @internal
@ -62,15 +62,6 @@ export function useFieldDisplayNames(data: DataFrame[], filter?: (field: Field)
}, [data, filter]);
}
const fieldTypeIcons: { [key in FieldType]: IconName } = {
time: 'clock-nine',
string: 'font',
number: 'calculator-alt',
boolean: 'toggle-on',
trace: 'info-circle',
other: 'brackets-curly',
};
/**
* @internal
*/
@ -93,7 +84,7 @@ export function useSelectOptions(
options.push({
value: name,
label: name,
icon: field ? fieldTypeIcons[field.type] : undefined,
icon: field ? getFieldTypeIcon(field) : undefined,
});
}
for (const name of displayNames.raw) {

View File

@ -6,14 +6,16 @@ import { getTableStyles, TableStyles } from './styles';
import { useStyles2 } from '../../themes';
import { Filter } from './Filter';
import { Icon } from '../Icon/Icon';
import { getFieldTypeIcon } from '../../types';
export interface HeaderRowProps {
headerGroups: HeaderGroup[];
data: DataFrame;
showTypeIcons?: boolean;
}
export const HeaderRow = (props: HeaderRowProps) => {
const { headerGroups, data } = props;
const { headerGroups, data, showTypeIcons } = props;
const e2eSelectorsTable = selectors.components.Panels.Visualization.Table;
const tableStyles = useStyles2(getTableStyles);
@ -30,7 +32,7 @@ export const HeaderRow = (props: HeaderRowProps) => {
role="row"
>
{headerGroup.headers.map((column: Column, index: number) =>
renderHeaderCell(column, tableStyles, data.fields[index])
renderHeaderCell(column, tableStyles, data.fields[index], showTypeIcons)
)}
</div>
);
@ -39,7 +41,7 @@ export const HeaderRow = (props: HeaderRowProps) => {
);
};
function renderHeaderCell(column: any, tableStyles: TableStyles, field?: Field) {
function renderHeaderCell(column: any, tableStyles: TableStyles, field?: Field, showTypeIcons?: boolean) {
const headerProps = column.getHeaderProps();
if (column.canResize) {
@ -58,6 +60,9 @@ function renderHeaderCell(column: any, tableStyles: TableStyles, field?: Field)
className={tableStyles.headerCellLabel}
title={column.render('Header')}
>
{showTypeIcons && (
<Icon name={getFieldTypeIcon(field)} title={field?.type} size="sm" style={{ marginRight: '8px' }} />
)}
<div>{column.render('Header')}</div>
<div>
{column.isSorted && (column.isSortedDesc ? <Icon name="arrow-down" /> : <Icon name="arrow-up" />)}

View File

@ -38,6 +38,7 @@ export interface Props {
/** Minimal column width specified in pixels */
columnMinWidth?: number;
noHeader?: boolean;
showTypeIcons?: boolean;
resizable?: boolean;
initialSortBy?: TableSortByFieldState[];
onColumnResize?: TableColumnResizeActionCallback;
@ -124,6 +125,7 @@ export const Table: FC<Props> = memo((props: Props) => {
resizable = true,
initialSortBy,
footerValues,
showTypeIcons,
} = props;
const tableStyles = useStyles2(getTableStyles);
@ -204,7 +206,7 @@ export const Table: FC<Props> = memo((props: Props) => {
<div {...getTableProps()} className={tableStyles.table} aria-label={ariaLabel} role="table">
<CustomScrollbar hideVerticalTrack={true}>
<div style={{ width: totalColumnsWidth ? `${totalColumnsWidth}px` : '100%' }}>
{!noHeader && <HeaderRow data={data} headerGroups={headerGroups} />}
{!noHeader && <HeaderRow data={data} headerGroups={headerGroups} showTypeIcons={showTypeIcons} />}
{rows.length > 0 ? (
<FixedSizeList
height={height - headerHeight}

View File

@ -1,3 +1,4 @@
import { Field, FieldType } from '@grafana/data';
import { ComponentSize } from './size';
export type IconType = 'mono' | 'default';
export type IconSize = ComponentSize | 'xl' | 'xxl' | 'xxxl';
@ -154,3 +155,24 @@ export const getAvailableIcons = () =>
type BrandIconNames = 'google' | 'microsoft' | 'github' | 'gitlab' | 'okta';
export type IconName = ReturnType<typeof getAvailableIcons>[number] | BrandIconNames;
/** Get the icon for a given field type */
export function getFieldTypeIcon(field?: Field): IconName {
if (field) {
switch (field.type) {
case FieldType.time:
return 'clock-nine';
case FieldType.string:
return 'font';
case FieldType.number:
return 'calculator-alt';
case FieldType.boolean:
return 'toggle-on';
case FieldType.trace:
return 'info-circle';
case FieldType.other:
return 'brackets-curly';
}
}
return 'question-circle';
}

View File

@ -19,6 +19,7 @@ export function PanelEditorTableView({ width, height, panel, dashboard }: Props)
const [options, setOptions] = useState<PanelOptions>({
frameIndex: 0,
showHeader: true,
showTypeIcons: true,
});
// Subscribe to panel event

View File

@ -228,7 +228,7 @@ export class InspectDataTab extends PureComponent<Props, State> {
return (
<div style={{ width, height }}>
<Table width={width} height={height} data={dataFrame} />
<Table width={width} height={height} data={dataFrame} showTypeIcons={true} />
</div>
);
}}

View File

@ -86,6 +86,7 @@ export class TablePanel extends Component<Props> {
width={width}
data={frame}
noHeader={!options.showHeader}
showTypeIcons={options.showTypeIcons}
resizable={true}
initialSortBy={options.sortBy}
onSortByChange={this.onSortByChange}

View File

@ -25,6 +25,7 @@ Family: {
PanelOptions: {
frameIndex: number | *0
showHeader: bool | *true
showTypeIcons: bool | *false
sortBy?: [...ui.TableSortByFieldState]
}
PanelFieldConfig: {

View File

@ -14,12 +14,14 @@ export const modelVersion = Object.freeze([1, 0]);
export interface PanelOptions {
frameIndex: number;
showHeader: boolean;
showTypeIcons?: boolean;
sortBy?: TableSortByFieldState[];
}
export const defaultPanelOptions: PanelOptions = {
frameIndex: 0,
showHeader: true,
showTypeIcons: false,
};
export interface PanelFieldConfig {