diff --git a/packages/grafana-schema/src/common/common.gen.ts b/packages/grafana-schema/src/common/common.gen.ts index 4b1ba194812..ad1169b3c96 100644 --- a/packages/grafana-schema/src/common/common.gen.ts +++ b/packages/grafana-schema/src/common/common.gen.ts @@ -690,6 +690,7 @@ export interface Labels {} * modes are deprecated in favor of new cell subOptions */ export enum TableCellDisplayMode { + Actions = 'actions', Auto = 'auto', BasicGauge = 'basic', ColorBackground = 'color-background', @@ -784,6 +785,13 @@ export interface TableDataLinksCellOptions { type: TableCellDisplayMode.DataLinks; } +/** + * Show actions in the cell + */ +export interface TableActionsCellOptions { + type: TableCellDisplayMode.Actions; +} + /** * Gauge cell options */ @@ -825,7 +833,7 @@ export enum TableCellHeight { * Table cell options. Each cell has a display mode * and other potential options for that display. */ -export type TableCellOptions = (TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TableDataLinksCellOptions | TableJsonViewCellOptions); +export type TableCellOptions = (TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TableDataLinksCellOptions | TableActionsCellOptions | TableJsonViewCellOptions); /** * Use UTC/GMT timezone diff --git a/packages/grafana-schema/src/common/table.cue b/packages/grafana-schema/src/common/table.cue index 9dc54fe5ec4..7548275ada7 100644 --- a/packages/grafana-schema/src/common/table.cue +++ b/packages/grafana-schema/src/common/table.cue @@ -4,7 +4,7 @@ package common // in the table such as colored text, JSON, gauge, etc. // The color-background-solid, gradient-gauge, and lcd-gauge // modes are deprecated in favor of new cell subOptions -TableCellDisplayMode: "auto" | "color-text" | "color-background" | "color-background-solid" | "gradient-gauge" | "lcd-gauge" | "json-view" | "basic" | "image" | "gauge" | "sparkline" | "data-links" | "custom" @cuetsy(kind="enum",memberNames="Auto|ColorText|ColorBackground|ColorBackgroundSolid|GradientGauge|LcdGauge|JSONView|BasicGauge|Image|Gauge|Sparkline|DataLinks|Custom") +TableCellDisplayMode: "auto" | "color-text" | "color-background" | "color-background-solid" | "gradient-gauge" | "lcd-gauge" | "json-view" | "basic" | "image" | "gauge" | "sparkline" | "data-links" | "custom" | "actions" @cuetsy(kind="enum",memberNames="Auto|ColorText|ColorBackground|ColorBackgroundSolid|GradientGauge|LcdGauge|JSONView|BasicGauge|Image|Gauge|Sparkline|DataLinks|Custom|Actions") // Display mode to the "Colored Background" display // mode for table cells. Either displays a solid color (basic mode) @@ -57,6 +57,11 @@ TableDataLinksCellOptions: { type: TableCellDisplayMode & "data-links" } @cuetsy(kind="interface") +// Show actions in the cell +TableActionsCellOptions: { + type: TableCellDisplayMode & "actions" +} @cuetsy(kind="interface") + // Gauge cell options TableBarGaugeCellOptions: { type: TableCellDisplayMode & "gauge" @@ -84,7 +89,7 @@ TableCellHeight: "sm" | "md" | "lg" | "auto" @cuetsy(kind="enum") // Table cell options. Each cell has a display mode // and other potential options for that display. -TableCellOptions: TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TableDataLinksCellOptions | TableJsonViewCellOptions @cuetsy(kind="type") +TableCellOptions: TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TableDataLinksCellOptions | TableActionsCellOptions | TableJsonViewCellOptions @cuetsy(kind="type") // Field options for each field within a table (e.g 10, "The String", 64.20, etc.) // Generally defines alignment, filtering capabilties, display options, etc. diff --git a/packages/grafana-ui/src/components/Table/ActionsCell.tsx b/packages/grafana-ui/src/components/Table/ActionsCell.tsx new file mode 100644 index 00000000000..00a62567ada --- /dev/null +++ b/packages/grafana-ui/src/components/Table/ActionsCell.tsx @@ -0,0 +1,26 @@ +import { css, cx } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; +import { ActionButton } from '../Actions/ActionButton'; + +import { TableCellProps } from './types'; + +export const ActionsCell = (props: TableCellProps) => { + const { cellProps, tableStyles, actions } = props; + + const styles = useStyles2(getStyles); + + return ( +
+ {actions && actions.map((action, i) => )} +
+ ); +}; + +const getStyles = (theme: GrafanaTheme2) => ({ + buttonsGap: css({ + gap: 6, + }), +}); diff --git a/packages/grafana-ui/src/components/Table/utils.ts b/packages/grafana-ui/src/components/Table/utils.ts index 578aee1ef96..8a419210ecc 100644 --- a/packages/grafana-ui/src/components/Table/utils.ts +++ b/packages/grafana-ui/src/components/Table/utils.ts @@ -1,25 +1,25 @@ import { Property } from 'csstype'; import { clone, sampleSize } from 'lodash'; import memoize from 'micro-memoize'; -import { Row, HeaderGroup } from 'react-table'; +import { HeaderGroup, Row } from 'react-table'; import tinycolor from 'tinycolor2'; import { DataFrame, + DisplayValue, + DisplayValueAlignmentFactors, Field, + fieldReducers, FieldType, formattedValueToString, - getFieldDisplayName, - SelectableValue, - fieldReducers, getDisplayProcessor, - reduceField, + getFieldDisplayName, GrafanaTheme2, isDataFrame, isDataFrameWithValue, isTimeSeriesFrame, - DisplayValueAlignmentFactors, - DisplayValue, + reduceField, + SelectableValue, } from '@grafana/data'; import { BarGaugeDisplayMode, @@ -30,6 +30,7 @@ import { import { getTextColorForAlphaBackground } from '../../utils'; +import { ActionsCell } from './ActionsCell'; import { BarGaugeCell } from './BarGaugeCell'; import { DataLinksCell } from './DataLinksCell'; import { DefaultCell } from './DefaultCell'; @@ -41,13 +42,13 @@ import { RowExpander } from './RowExpander'; import { SparklineCell } from './SparklineCell'; import { TableStyles } from './styles'; import { + CellColors, CellComponent, - TableCellOptions, - TableFieldOptions, FooterItem, GrafanaTableColumn, + TableCellOptions, + TableFieldOptions, TableFooterCalc, - CellColors, } from './types'; export const EXPANDER_WIDTH = 50; @@ -191,6 +192,8 @@ export function getCellComponent(displayMode: TableCellDisplayMode, field: Field return JSONViewCell; case TableCellDisplayMode.DataLinks: return DataLinksCell; + case TableCellDisplayMode.Actions: + return ActionsCell; } if (field.type === FieldType.geo) { diff --git a/public/app/plugins/panel/table/TableCellOptionEditor.tsx b/public/app/plugins/panel/table/TableCellOptionEditor.tsx index 4a9676abdf3..cff753a5344 100644 --- a/public/app/plugins/panel/table/TableCellOptionEditor.tsx +++ b/public/app/plugins/panel/table/TableCellOptionEditor.tsx @@ -3,6 +3,7 @@ import { merge } from 'lodash'; import { useState } from 'react'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { TableCellOptions } from '@grafana/schema'; import { Field, Select, TableCellDisplayMode, useStyles2 } from '@grafana/ui'; @@ -81,7 +82,7 @@ export const TableCellOptionEditor = ({ value, onChange }: Props) => { ); }; -const cellDisplayModeOptions: Array> = [ +let cellDisplayModeOptions: Array> = [ { value: { type: TableCellDisplayMode.Auto }, label: 'Auto' }, { value: { type: TableCellDisplayMode.Sparkline }, label: 'Sparkline' }, { value: { type: TableCellDisplayMode.ColorText }, label: 'Colored text' }, @@ -92,6 +93,13 @@ const cellDisplayModeOptions: Array> = [ { value: { type: TableCellDisplayMode.Image }, label: 'Image' }, ]; +if (config.featureToggles.vizActions) { + cellDisplayModeOptions = [ + ...cellDisplayModeOptions, + { value: { type: TableCellDisplayMode.Actions }, label: 'Actions' }, + ]; +} + const getStyles = (theme: GrafanaTheme2) => ({ fixBottomMargin: css({ marginBottom: theme.spacing(-2),