3
0
mirror of https://github.com/grafana/grafana.git synced 2025-02-25 18:55:37 -06:00

Transformations: Enable / disable toggle for transformation rows ()

* Disable transform feature

* Change icon

* Added more clear way to show it's disabled
This commit is contained in:
Torkel Ödegaard 2021-07-13 09:36:51 +02:00 committed by GitHub
parent 5d01add7da
commit beca793008
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 121 additions and 7 deletions
packages/grafana-data/src
public/app
core/components/QueryOperationRow
features/dashboard/components/TransformationsEditor

View File

@ -0,0 +1,75 @@
import { ReducerID } from './fieldReducer';
import { DataTransformerID } from './transformers/ids';
import { toDataFrame } from '../dataframe/processDataFrame';
import { mockTransformationsRegistry } from '../utils/tests/mockTransformationsRegistry';
import { reduceTransformer } from './transformers/reduce';
import { filterFieldsByNameTransformer } from './transformers/filterByName';
import { transformDataFrame } from './transformDataFrame';
import { FieldType } from '../types';
const seriesAWithSingleField = toDataFrame({
name: 'A',
fields: [
{ name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000] },
{ name: 'temperature', type: FieldType.number, values: [3, 4, 5, 6] },
],
});
describe('transformDataFrame', () => {
beforeAll(() => {
mockTransformationsRegistry([reduceTransformer, filterFieldsByNameTransformer]);
});
it('Applies all transforms', async () => {
const cfg = [
{
id: DataTransformerID.reduce,
options: {
reducers: [ReducerID.first],
},
},
{
id: DataTransformerID.filterFieldsByName,
options: {
include: {
pattern: '/First/',
},
},
},
];
await expect(transformDataFrame(cfg, [seriesAWithSingleField])).toEmitValuesWith((received) => {
const processed = received[0];
expect(processed[0].length).toEqual(1);
expect(processed[0].fields.length).toEqual(1);
expect(processed[0].fields[0].values.get(0)).toEqual(3);
});
});
it('Skips over disabled transforms', async () => {
const cfg = [
{
id: DataTransformerID.reduce,
options: {
reducers: [ReducerID.first],
},
},
{
id: DataTransformerID.filterFieldsByName,
disabled: true,
options: {
include: {
pattern: '/First/',
},
},
},
];
await expect(transformDataFrame(cfg, [seriesAWithSingleField])).toEmitValuesWith((received) => {
const processed = received[0];
expect(processed[0].length).toEqual(1);
expect(processed[0].fields.length).toEqual(2);
expect(processed[0].fields[0].values.get(0)).toEqual('temperature');
});
});
});

View File

@ -60,6 +60,11 @@ export function transformDataFrame(options: DataTransformerConfig[], data: DataF
for (let index = 0; index < options.length; index++) {
const config = options[index];
if (config.disabled) {
continue;
}
operators.push(getOperator(config));
}

View File

@ -19,6 +19,10 @@ export interface DataTransformerConfig<TOptions = any> {
* Unique identifier of transformer
*/
id: string;
/**
* Disabled transformations are skipped
*/
disabled?: boolean;
/**
* Options to be passed to the transformer
*/

View File

@ -1,7 +1,7 @@
import React, { useState, useCallback } from 'react';
import { Icon, renderOrCallToRender, stylesFactory, useTheme } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
import { css } from '@emotion/css';
import { css, cx } from '@emotion/css';
import { useUpdateEffect } from 'react-use';
import { Draggable } from 'react-beautiful-dnd';
@ -16,6 +16,7 @@ interface QueryOperationRowProps {
children: React.ReactNode;
isOpen?: boolean;
draggable?: boolean;
disabled?: boolean;
}
export type QueryOperationRowRenderProp = ((props: QueryOperationRowRenderProps) => React.ReactNode) | React.ReactNode;
@ -34,6 +35,7 @@ export const QueryOperationRow: React.FC<QueryOperationRowProps> = ({
onClose,
onOpen,
isOpen,
disabled,
draggable,
index,
id,
@ -80,7 +82,7 @@ export const QueryOperationRow: React.FC<QueryOperationRowProps> = ({
/>
{title && (
<div className={styles.titleWrapper} onClick={onRowToggle} aria-label="Query operation row title">
<div className={styles.title}>{titleElement}</div>
<div className={cx(styles.title, disabled && styles.disabled)}>{titleElement}</div>
</div>
)}
{headerElementRendered}
@ -167,6 +169,9 @@ const getQueryOperationRowStyles = stylesFactory((theme: GrafanaTheme) => {
margin-top: ${theme.spacing.inlineFormMargin};
margin-left: ${theme.spacing.lg};
`,
disabled: css`
color: ${theme.colors.textWeak};
`,
};
});

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback } from 'react';
import { DataFrame, DataTransformerConfig, TransformerRegistryItem } from '@grafana/data';
import { HorizontalGroup } from '@grafana/ui';
@ -34,6 +34,18 @@ export const TransformationOperationRow: React.FC<TransformationOperationRowProp
}) => {
const [showDebug, toggleDebug] = useToggle(false);
const [showHelp, toggleHelp] = useToggle(false);
const disabled = configs[index].transformation.disabled;
const onDisableToggle = useCallback(
(index: number) => {
const current = configs[index].transformation;
onChange(index, {
...current,
disabled: current.disabled ? undefined : true,
});
},
[onChange, configs]
);
const renderActions = ({ isOpen }: QueryOperationRowRenderProps) => {
return (
@ -46,13 +58,26 @@ export const TransformationOperationRow: React.FC<TransformationOperationRowProp
active={showHelp}
/>
<QueryOperationAction title="Debug" disabled={!isOpen} icon="bug" onClick={toggleDebug} active={showDebug} />
<QueryOperationAction
title="Disable/Enable transformation"
icon={disabled ? 'eye-slash' : 'eye'}
onClick={() => onDisableToggle(index)}
active={disabled}
/>
<QueryOperationAction title="Remove" icon="trash-alt" onClick={() => onRemove(index)} />
</HorizontalGroup>
);
};
return (
<QueryOperationRow id={id} index={index} title={uiConfig.name} draggable actions={renderActions}>
<QueryOperationRow
id={id}
index={index}
title={uiConfig.name}
draggable
actions={renderActions}
disabled={disabled}
>
{showHelp && <OperationRowHelp markdown={prepMarkdown(uiConfig)} />}
<TransformationEditor
debugMode={showDebug}
@ -72,8 +97,8 @@ function prepMarkdown(uiConfig: TransformerRegistryItem<any>) {
return `
${helpMarkdown}
<a href="https://grafana.com/docs/grafana/latest/panels/transformations/?utm_source=grafana" target="_blank" rel="noreferrer">
Read more on the documentation site
</a>
Go the <a href="https://grafana.com/docs/grafana/latest/panels/transformations/?utm_source=grafana" target="_blank" rel="noreferrer">
transformation documentation
</a> for more.
`;
}