mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Transformations: Convert calculate field transformer editor to functional component (#77777)
convert class based transformer editor to functional component
This commit is contained in:
parent
9e54012407
commit
59df27cd27
@ -5087,8 +5087,7 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
[0, 0, 0, "Do not use any type assertions.", "4"]
|
||||||
[0, 0, 0, "Do not use any type assertions.", "5"]
|
|
||||||
],
|
],
|
||||||
"public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx:5381": [
|
"public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { defaults } from 'lodash';
|
import { defaults } from 'lodash';
|
||||||
import React, { ChangeEvent } from 'react';
|
import React, { ChangeEvent, useEffect, useState } from 'react';
|
||||||
import { identity, of, OperatorFunction } from 'rxjs';
|
import { identity, of, OperatorFunction } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
@ -52,7 +52,6 @@ import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
|
|||||||
interface CalculateFieldTransformerEditorProps extends TransformerUIProps<CalculateFieldTransformerOptions> {}
|
interface CalculateFieldTransformerEditorProps extends TransformerUIProps<CalculateFieldTransformerOptions> {}
|
||||||
|
|
||||||
interface CalculateFieldTransformerEditorState {
|
interface CalculateFieldTransformerEditorState {
|
||||||
include: string[];
|
|
||||||
names: string[];
|
names: string[];
|
||||||
selected: string[];
|
selected: string[];
|
||||||
}
|
}
|
||||||
@ -75,47 +74,30 @@ const okTypes = new Set<FieldType>([FieldType.time, FieldType.number, FieldType.
|
|||||||
|
|
||||||
const labelWidth = 16;
|
const labelWidth = 16;
|
||||||
|
|
||||||
export class CalculateFieldTransformerEditor extends React.PureComponent<
|
export const CalculateFieldTransformerEditor = (props: CalculateFieldTransformerEditorProps) => {
|
||||||
CalculateFieldTransformerEditorProps,
|
const { options, onChange, input } = props;
|
||||||
CalculateFieldTransformerEditorState
|
const configuredOptions = options?.reduce?.include;
|
||||||
> {
|
|
||||||
constructor(props: CalculateFieldTransformerEditorProps) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
const [state, setState] = useState<CalculateFieldTransformerEditorState>({ names: [], selected: [] });
|
||||||
include: props.options?.reduce?.include || [],
|
|
||||||
names: [],
|
|
||||||
selected: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
useEffect(() => {
|
||||||
this.initOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(oldProps: CalculateFieldTransformerEditorProps) {
|
|
||||||
if (this.props.input !== oldProps.input) {
|
|
||||||
this.initOptions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private initOptions() {
|
|
||||||
const { options } = this.props;
|
|
||||||
const configuredOptions = options?.reduce?.include || [];
|
|
||||||
const ctx = { interpolate: (v: string) => v };
|
const ctx = { interpolate: (v: string) => v };
|
||||||
const subscription = of(this.props.input)
|
const subscription = of(input)
|
||||||
.pipe(
|
.pipe(
|
||||||
standardTransformers.ensureColumnsTransformer.operator(null, ctx),
|
standardTransformers.ensureColumnsTransformer.operator(null, ctx),
|
||||||
this.extractAllNames(),
|
extractAllNames(),
|
||||||
this.getVariableNames(),
|
getVariableNames(),
|
||||||
this.extractNamesAndSelected(configuredOptions)
|
extractNamesAndSelected(configuredOptions || [])
|
||||||
)
|
)
|
||||||
.subscribe(({ selected, names }) => {
|
.subscribe(({ selected, names }) => {
|
||||||
this.setState({ names, selected }, () => subscription.unsubscribe());
|
setState({ names, selected });
|
||||||
});
|
});
|
||||||
}
|
return () => {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
};
|
||||||
|
}, [input, configuredOptions]);
|
||||||
|
|
||||||
private getVariableNames(): OperatorFunction<string[], string[]> {
|
const getVariableNames = (): OperatorFunction<string[], string[]> => {
|
||||||
if (!cfg.featureToggles.transformationsVariableSupport) {
|
if (!cfg.featureToggles.transformationsVariableSupport) {
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
@ -127,9 +109,9 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
return input;
|
return input;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
private extractAllNames(): OperatorFunction<DataFrame[], string[]> {
|
const extractAllNames = (): OperatorFunction<DataFrame[], string[]> => {
|
||||||
return (source) =>
|
return (source) =>
|
||||||
source.pipe(
|
source.pipe(
|
||||||
map((input) => {
|
map((input) => {
|
||||||
@ -154,11 +136,11 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
return allNames;
|
return allNames;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
private extractNamesAndSelected(
|
const extractNamesAndSelected = (
|
||||||
configuredOptions: string[]
|
configuredOptions: string[]
|
||||||
): OperatorFunction<string[], { names: string[]; selected: string[] }> {
|
): OperatorFunction<string[], { names: string[]; selected: string[] }> => {
|
||||||
return (source) =>
|
return (source) =>
|
||||||
source.pipe(
|
source.pipe(
|
||||||
map((allNames) => {
|
map((allNames) => {
|
||||||
@ -179,28 +161,16 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
return { names, selected };
|
return { names, selected };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
onToggleReplaceFields = (e: React.FormEvent<HTMLInputElement>) => {
|
const onToggleReplaceFields = (e: React.FormEvent<HTMLInputElement>) => {
|
||||||
const { options } = this.props;
|
onChange({
|
||||||
this.props.onChange({
|
|
||||||
...options,
|
...options,
|
||||||
replaceFields: e.currentTarget.checked,
|
replaceFields: e.currentTarget.checked,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onToggleRowIndexAsPercentile = (e: React.FormEvent<HTMLInputElement>) => {
|
const onModeChanged = (value: SelectableValue<CalculateFieldMode>) => {
|
||||||
const { options } = this.props;
|
|
||||||
this.props.onChange({
|
|
||||||
...options,
|
|
||||||
index: {
|
|
||||||
asPercentile: e.currentTarget.checked,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onModeChanged = (value: SelectableValue<CalculateFieldMode>) => {
|
|
||||||
const { options, onChange } = this.props;
|
|
||||||
const mode = value.value ?? CalculateFieldMode.BinaryOperation;
|
const mode = value.value ?? CalculateFieldMode.BinaryOperation;
|
||||||
if (mode === CalculateFieldMode.WindowFunctions) {
|
if (mode === CalculateFieldMode.WindowFunctions) {
|
||||||
options.window = options.window ?? defaultWindowOptions;
|
options.window = options.window ?? defaultWindowOptions;
|
||||||
@ -211,67 +181,42 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onAliasChanged = (evt: ChangeEvent<HTMLInputElement>) => {
|
const onAliasChanged = (evt: ChangeEvent<HTMLInputElement>) => {
|
||||||
const { options } = this.props;
|
onChange({
|
||||||
this.props.onChange({
|
|
||||||
...options,
|
...options,
|
||||||
alias: evt.target.value,
|
alias: evt.target.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Cumulative functions
|
// Row index
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
updateReduceOptions = (v: ReduceOptions) => {
|
const onToggleRowIndexAsPercentile = (e: React.FormEvent<HTMLInputElement>) => {
|
||||||
const { options, onChange } = this.props;
|
|
||||||
onChange({
|
onChange({
|
||||||
...options,
|
...options,
|
||||||
reduce: v,
|
index: {
|
||||||
|
asPercentile: e.currentTarget.checked,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onFieldToggle = (fieldName: string) => {
|
const renderRowIndex = (options?: IndexOptions) => {
|
||||||
const { selected } = this.state;
|
|
||||||
if (selected.indexOf(fieldName) > -1) {
|
|
||||||
this.onChange(selected.filter((s) => s !== fieldName));
|
|
||||||
} else {
|
|
||||||
this.onChange([...selected, fieldName]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onChange = (selected: string[]) => {
|
|
||||||
this.setState({ selected });
|
|
||||||
const { reduce } = this.props.options;
|
|
||||||
this.updateReduceOptions({
|
|
||||||
...reduce!,
|
|
||||||
include: selected,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onStatsChange = (stats: string[]) => {
|
|
||||||
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
|
||||||
|
|
||||||
const { reduce } = this.props.options;
|
|
||||||
this.updateReduceOptions({ ...reduce, reducer });
|
|
||||||
};
|
|
||||||
|
|
||||||
renderRowIndex(options?: IndexOptions) {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<InlineField labelWidth={labelWidth} label="As percentile" tooltip="Transform the row index as a percentile.">
|
<InlineField labelWidth={labelWidth} label="As percentile" tooltip="Transform the row index as a percentile.">
|
||||||
<InlineSwitch value={!!options?.asPercentile} onChange={this.onToggleRowIndexAsPercentile} />
|
<InlineSwitch value={!!options?.asPercentile} onChange={onToggleRowIndexAsPercentile} />
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Window functions
|
// Window functions
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
updateWindowOptions = (v: WindowOptions) => {
|
const updateWindowOptions = (v: WindowOptions) => {
|
||||||
const { options, onChange } = this.props;
|
const { options, onChange } = props;
|
||||||
onChange({
|
onChange({
|
||||||
...options,
|
...options,
|
||||||
mode: CalculateFieldMode.WindowFunctions,
|
mode: CalculateFieldMode.WindowFunctions,
|
||||||
@ -279,26 +224,26 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onWindowFieldChange = (v: SelectableValue<string>) => {
|
const onWindowFieldChange = (v: SelectableValue<string>) => {
|
||||||
const { window } = this.props.options;
|
const { window } = options;
|
||||||
this.updateWindowOptions({
|
updateWindowOptions({
|
||||||
...window!,
|
...window!,
|
||||||
field: v.value!,
|
field: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onWindowSizeChange = (v?: number) => {
|
const onWindowSizeChange = (v?: number) => {
|
||||||
const { window } = this.props.options;
|
const { window } = options;
|
||||||
this.updateWindowOptions({
|
updateWindowOptions({
|
||||||
...window!,
|
...window!,
|
||||||
windowSize: v && window?.windowSizeMode === WindowSizeMode.Percentage ? v / 100 : v,
|
windowSize: v && window?.windowSizeMode === WindowSizeMode.Percentage ? v / 100 : v,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onWindowSizeModeChange = (val: string) => {
|
const onWindowSizeModeChange = (val: string) => {
|
||||||
const { window } = this.props.options;
|
const { window } = options;
|
||||||
const mode = val as WindowSizeMode;
|
const mode = val as WindowSizeMode;
|
||||||
this.updateWindowOptions({
|
updateWindowOptions({
|
||||||
...window!,
|
...window!,
|
||||||
windowSize: window?.windowSize
|
windowSize: window?.windowSize
|
||||||
? mode === WindowSizeMode.Percentage
|
? mode === WindowSizeMode.Percentage
|
||||||
@ -309,23 +254,23 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onWindowStatsChange = (stats: string[]) => {
|
const onWindowStatsChange = (stats: string[]) => {
|
||||||
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
||||||
|
|
||||||
const { window } = this.props.options;
|
const { window } = options;
|
||||||
this.updateWindowOptions({ ...window, reducer });
|
updateWindowOptions({ ...window, reducer });
|
||||||
};
|
};
|
||||||
|
|
||||||
onTypeChange = (val: string) => {
|
const onTypeChange = (val: string) => {
|
||||||
const { window } = this.props.options;
|
const { window } = options;
|
||||||
this.updateWindowOptions({
|
updateWindowOptions({
|
||||||
...window!,
|
...window!,
|
||||||
windowAlignment: val as WindowAlignment,
|
windowAlignment: val as WindowAlignment,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderWindowFunctions(options?: WindowOptions) {
|
const renderWindowFunctions = (options?: WindowOptions) => {
|
||||||
const { names } = this.state;
|
const { names } = state;
|
||||||
options = defaults(options, { reducer: ReducerID.sum });
|
options = defaults(options, { reducer: ReducerID.sum });
|
||||||
const selectOptions = names.map((v) => ({ label: v, value: v }));
|
const selectOptions = names.map((v) => ({ label: v, value: v }));
|
||||||
const typeOptions = [
|
const typeOptions = [
|
||||||
@ -345,7 +290,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
options={selectOptions}
|
options={selectOptions}
|
||||||
className="min-width-18"
|
className="min-width-18"
|
||||||
value={options?.field}
|
value={options?.field}
|
||||||
onChange={this.onWindowFieldChange}
|
onChange={onWindowFieldChange}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField label="Calculation" labelWidth={labelWidth}>
|
<InlineField label="Calculation" labelWidth={labelWidth}>
|
||||||
@ -353,7 +298,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
allowMultiple={false}
|
allowMultiple={false}
|
||||||
className="width-18"
|
className="width-18"
|
||||||
stats={[options.reducer]}
|
stats={[options.reducer]}
|
||||||
onChange={this.onWindowStatsChange}
|
onChange={onWindowStatsChange}
|
||||||
defaultStat={ReducerID.mean}
|
defaultStat={ReducerID.mean}
|
||||||
filterOptions={(ext) =>
|
filterOptions={(ext) =>
|
||||||
ext.id === ReducerID.mean || ext.id === ReducerID.variance || ext.id === ReducerID.stdDev
|
ext.id === ReducerID.mean || ext.id === ReducerID.variance || ext.id === ReducerID.stdDev
|
||||||
@ -364,14 +309,14 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
<RadioButtonGroup
|
<RadioButtonGroup
|
||||||
value={options.windowAlignment ?? WindowAlignment.Trailing}
|
value={options.windowAlignment ?? WindowAlignment.Trailing}
|
||||||
options={typeOptions}
|
options={typeOptions}
|
||||||
onChange={this.onTypeChange}
|
onChange={onTypeChange}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField label="Window size mode">
|
<InlineField label="Window size mode">
|
||||||
<RadioButtonGroup
|
<RadioButtonGroup
|
||||||
value={options.windowSizeMode ?? WindowSizeMode.Percentage}
|
value={options.windowSizeMode ?? WindowSizeMode.Percentage}
|
||||||
options={windowSizeModeOptions}
|
options={windowSizeModeOptions}
|
||||||
onChange={this.onWindowSizeModeChange}
|
onChange={onWindowSizeModeChange}
|
||||||
></RadioButtonGroup>
|
></RadioButtonGroup>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField
|
<InlineField
|
||||||
@ -391,26 +336,52 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
? options.windowSize * 100
|
? options.windowSize * 100
|
||||||
: options.windowSize
|
: options.windowSize
|
||||||
}
|
}
|
||||||
onChange={this.onWindowSizeChange}
|
onChange={onWindowSizeChange}
|
||||||
></NumberInput>
|
></NumberInput>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Reduce by Row
|
// Reduce by Row
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
onReducerStatsChange = (stats: string[]) => {
|
const updateReduceOptions = (v: ReduceOptions) => {
|
||||||
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
const { onChange } = props;
|
||||||
|
onChange({
|
||||||
const { reduce } = this.props.options;
|
...options,
|
||||||
this.updateReduceOptions({ ...reduce, reducer });
|
reduce: v,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderReduceRow(options?: ReduceOptions) {
|
const onFieldToggle = (fieldName: string) => {
|
||||||
const { names, selected } = this.state;
|
const { selected } = state;
|
||||||
|
if (selected.indexOf(fieldName) > -1) {
|
||||||
|
onReduceFieldsChanged(selected.filter((s) => s !== fieldName));
|
||||||
|
} else {
|
||||||
|
onReduceFieldsChanged([...selected, fieldName]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onReduceFieldsChanged = (selected: string[]) => {
|
||||||
|
setState({ ...state, ...{ selected } });
|
||||||
|
const { reduce } = options;
|
||||||
|
updateReduceOptions({
|
||||||
|
...reduce!,
|
||||||
|
include: selected,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStatsChange = (stats: string[]) => {
|
||||||
|
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
||||||
|
|
||||||
|
const { reduce } = options;
|
||||||
|
updateReduceOptions({ ...reduce, reducer });
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderReduceRow = (options?: ReduceOptions) => {
|
||||||
|
const { names, selected } = state;
|
||||||
options = defaults(options, { reducer: ReducerID.sum });
|
options = defaults(options, { reducer: ReducerID.sum });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -422,7 +393,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
<FilterPill
|
<FilterPill
|
||||||
key={`${o}/${i}`}
|
key={`${o}/${i}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.onFieldToggle(o);
|
onFieldToggle(o);
|
||||||
}}
|
}}
|
||||||
label={o}
|
label={o}
|
||||||
selected={selected.indexOf(o) > -1}
|
selected={selected.indexOf(o) > -1}
|
||||||
@ -436,27 +407,26 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
allowMultiple={false}
|
allowMultiple={false}
|
||||||
className="width-18"
|
className="width-18"
|
||||||
stats={[options.reducer]}
|
stats={[options.reducer]}
|
||||||
onChange={this.onStatsChange}
|
onChange={onStatsChange}
|
||||||
defaultStat={ReducerID.sum}
|
defaultStat={ReducerID.sum}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Cumulative Operator
|
// Cumulative Operator
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
onCumulativeStatsChange = (stats: string[]) => {
|
const onCumulativeStatsChange = (stats: string[]) => {
|
||||||
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
const reducer = stats.length ? (stats[0] as ReducerID) : ReducerID.sum;
|
||||||
|
|
||||||
const { reduce } = this.props.options;
|
const { cumulative } = options;
|
||||||
this.updateCumulativeOptions({ ...reduce, reducer });
|
updateCumulativeOptions({ ...cumulative, reducer });
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCumulativeOptions = (v: CumulativeOptions) => {
|
const updateCumulativeOptions = (v: CumulativeOptions) => {
|
||||||
const { options, onChange } = this.props;
|
|
||||||
onChange({
|
onChange({
|
||||||
...options,
|
...options,
|
||||||
mode: CalculateFieldMode.CumulativeFunctions,
|
mode: CalculateFieldMode.CumulativeFunctions,
|
||||||
@ -464,16 +434,16 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onCumulativeFieldChange = (v: SelectableValue<string>) => {
|
const onCumulativeFieldChange = (v: SelectableValue<string>) => {
|
||||||
const { cumulative } = this.props.options;
|
const { cumulative } = options;
|
||||||
this.updateCumulativeOptions({
|
updateCumulativeOptions({
|
||||||
...cumulative!,
|
...cumulative!,
|
||||||
field: v.value!,
|
field: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderCumulativeFunctions(options?: CumulativeOptions) {
|
const renderCumulativeFunctions = (options?: CumulativeOptions) => {
|
||||||
const { names } = this.state;
|
const { names } = state;
|
||||||
options = defaults(options, { reducer: ReducerID.sum });
|
options = defaults(options, { reducer: ReducerID.sum });
|
||||||
const selectOptions = names.map((v) => ({ label: v, value: v }));
|
const selectOptions = names.map((v) => ({ label: v, value: v }));
|
||||||
|
|
||||||
@ -485,7 +455,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
options={selectOptions}
|
options={selectOptions}
|
||||||
className="min-width-18"
|
className="min-width-18"
|
||||||
value={options?.field}
|
value={options?.field}
|
||||||
onChange={this.onCumulativeFieldChange}
|
onChange={onCumulativeFieldChange}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField label="Calculation" labelWidth={labelWidth}>
|
<InlineField label="Calculation" labelWidth={labelWidth}>
|
||||||
@ -493,21 +463,20 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
allowMultiple={false}
|
allowMultiple={false}
|
||||||
className="width-18"
|
className="width-18"
|
||||||
stats={[options.reducer]}
|
stats={[options.reducer]}
|
||||||
onChange={this.onCumulativeStatsChange}
|
onChange={onCumulativeStatsChange}
|
||||||
defaultStat={ReducerID.sum}
|
defaultStat={ReducerID.sum}
|
||||||
filterOptions={(ext) => ext.id === ReducerID.sum || ext.id === ReducerID.mean}
|
filterOptions={(ext) => ext.id === ReducerID.sum || ext.id === ReducerID.mean}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Binary Operator
|
// Binary Operator
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
updateBinaryOptions = (v: BinaryOptions) => {
|
const updateBinaryOptions = (v: BinaryOptions) => {
|
||||||
const { options, onChange } = this.props;
|
|
||||||
onChange({
|
onChange({
|
||||||
...options,
|
...options,
|
||||||
mode: CalculateFieldMode.BinaryOperation,
|
mode: CalculateFieldMode.BinaryOperation,
|
||||||
@ -515,36 +484,36 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onBinaryLeftChanged = (v: SelectableValue<string>) => {
|
const onBinaryLeftChanged = (v: SelectableValue<string>) => {
|
||||||
const { binary } = this.props.options;
|
const { binary } = options;
|
||||||
this.updateBinaryOptions({
|
updateBinaryOptions({
|
||||||
...binary!,
|
...binary!,
|
||||||
left: v.value!,
|
left: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onBinaryRightChanged = (v: SelectableValue<string>) => {
|
const onBinaryRightChanged = (v: SelectableValue<string>) => {
|
||||||
const { binary } = this.props.options;
|
const { binary } = options;
|
||||||
this.updateBinaryOptions({
|
updateBinaryOptions({
|
||||||
...binary!,
|
...binary!,
|
||||||
right: v.value!,
|
right: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onBinaryOperationChanged = (v: SelectableValue<BinaryOperationID>) => {
|
const onBinaryOperationChanged = (v: SelectableValue<BinaryOperationID>) => {
|
||||||
const { binary } = this.props.options;
|
const { binary } = options;
|
||||||
this.updateBinaryOptions({
|
updateBinaryOptions({
|
||||||
...binary!,
|
...binary!,
|
||||||
operator: v.value!,
|
operator: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderBinaryOperation(options?: BinaryOptions) {
|
const renderBinaryOperation = (options?: BinaryOptions) => {
|
||||||
options = defaults(options, { operator: BinaryOperationID.Add });
|
options = defaults(options, { operator: BinaryOperationID.Add });
|
||||||
|
|
||||||
let foundLeft = !options?.left;
|
let foundLeft = !options?.left;
|
||||||
let foundRight = !options?.right;
|
let foundRight = !options?.right;
|
||||||
const names = this.state.names.map((v) => {
|
const names = state.names.map((v) => {
|
||||||
if (v === options?.left) {
|
if (v === options?.left) {
|
||||||
foundLeft = true;
|
foundLeft = true;
|
||||||
}
|
}
|
||||||
@ -570,7 +539,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
options={leftNames}
|
options={leftNames}
|
||||||
className="min-width-18"
|
className="min-width-18"
|
||||||
value={options?.left}
|
value={options?.left}
|
||||||
onChange={this.onBinaryLeftChanged}
|
onChange={onBinaryLeftChanged}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField>
|
<InlineField>
|
||||||
@ -578,7 +547,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
className="width-4"
|
className="width-4"
|
||||||
options={ops}
|
options={ops}
|
||||||
value={options.operator ?? ops[0].value}
|
value={options.operator ?? ops[0].value}
|
||||||
onChange={this.onBinaryOperationChanged}
|
onChange={onBinaryOperationChanged}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField>
|
<InlineField>
|
||||||
@ -588,20 +557,19 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
className="min-width-10"
|
className="min-width-10"
|
||||||
options={rightNames}
|
options={rightNames}
|
||||||
value={options?.right}
|
value={options?.right}
|
||||||
onChange={this.onBinaryRightChanged}
|
onChange={onBinaryRightChanged}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// Unary Operator
|
// Unary Operator
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
updateUnaryOptions = (v: UnaryOptions) => {
|
const updateUnaryOptions = (v: UnaryOptions) => {
|
||||||
const { options, onChange } = this.props;
|
|
||||||
onChange({
|
onChange({
|
||||||
...options,
|
...options,
|
||||||
mode: CalculateFieldMode.UnaryOperation,
|
mode: CalculateFieldMode.UnaryOperation,
|
||||||
@ -609,27 +577,27 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onUnaryOperationChanged = (v: SelectableValue<UnaryOperationID>) => {
|
const onUnaryOperationChanged = (v: SelectableValue<UnaryOperationID>) => {
|
||||||
const { unary } = this.props.options;
|
const { unary } = options;
|
||||||
this.updateUnaryOptions({
|
updateUnaryOptions({
|
||||||
...unary!,
|
...unary!,
|
||||||
operator: v.value!,
|
operator: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onUnaryValueChanged = (v: SelectableValue<string>) => {
|
const onUnaryValueChanged = (v: SelectableValue<string>) => {
|
||||||
const { unary } = this.props.options;
|
const { unary } = options;
|
||||||
this.updateUnaryOptions({
|
updateUnaryOptions({
|
||||||
...unary!,
|
...unary!,
|
||||||
fieldName: v.value!,
|
fieldName: v.value!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderUnaryOperation(options?: UnaryOptions) {
|
const renderUnaryOperation = (options?: UnaryOptions) => {
|
||||||
options = defaults(options, { operator: UnaryOperationID.Abs });
|
options = defaults(options, { operator: UnaryOperationID.Abs });
|
||||||
|
|
||||||
let found = !options?.fieldName;
|
let found = !options?.fieldName;
|
||||||
const names = this.state.names.map((v) => {
|
const names = state.names.map((v) => {
|
||||||
if (v === options?.fieldName) {
|
if (v === options?.fieldName) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@ -646,7 +614,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
<>
|
<>
|
||||||
<InlineFieldRow>
|
<InlineFieldRow>
|
||||||
<InlineField label="Operation" labelWidth={labelWidth}>
|
<InlineField label="Operation" labelWidth={labelWidth}>
|
||||||
<Select options={ops} value={options.operator ?? ops[0].value} onChange={this.onUnaryOperationChanged} />
|
<Select options={ops} value={options.operator ?? ops[0].value} onChange={onUnaryOperationChanged} />
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineField label="(" labelWidth={2}>
|
<InlineField label="(" labelWidth={2}>
|
||||||
<Select
|
<Select
|
||||||
@ -654,55 +622,47 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
className="min-width-11"
|
className="min-width-11"
|
||||||
options={fieldName}
|
options={fieldName}
|
||||||
value={options?.fieldName}
|
value={options?.fieldName}
|
||||||
onChange={this.onUnaryValueChanged}
|
onChange={onUnaryValueChanged}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</InlineField>
|
||||||
<InlineLabel width={2}>)</InlineLabel>
|
<InlineLabel width={2}>)</InlineLabel>
|
||||||
</InlineFieldRow>
|
</InlineFieldRow>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------
|
const mode = options.mode ?? CalculateFieldMode.BinaryOperation;
|
||||||
// Render
|
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const { options } = this.props;
|
<>
|
||||||
|
<InlineField labelWidth={labelWidth} label="Mode">
|
||||||
const mode = options.mode ?? CalculateFieldMode.BinaryOperation;
|
<Select
|
||||||
|
className="width-18"
|
||||||
return (
|
options={calculationModes}
|
||||||
<>
|
value={calculationModes.find((v) => v.value === mode)}
|
||||||
<InlineField labelWidth={labelWidth} label="Mode">
|
onChange={onModeChanged}
|
||||||
<Select
|
/>
|
||||||
className="width-18"
|
</InlineField>
|
||||||
options={calculationModes}
|
{mode === CalculateFieldMode.BinaryOperation && renderBinaryOperation(options.binary)}
|
||||||
value={calculationModes.find((v) => v.value === mode)}
|
{mode === CalculateFieldMode.UnaryOperation && renderUnaryOperation(options.unary)}
|
||||||
onChange={this.onModeChanged}
|
{mode === CalculateFieldMode.ReduceRow && renderReduceRow(options.reduce)}
|
||||||
/>
|
{mode === CalculateFieldMode.CumulativeFunctions && renderCumulativeFunctions(options.cumulative)}
|
||||||
</InlineField>
|
{mode === CalculateFieldMode.WindowFunctions && renderWindowFunctions(options.window)}
|
||||||
{mode === CalculateFieldMode.BinaryOperation && this.renderBinaryOperation(options.binary)}
|
{mode === CalculateFieldMode.Index && renderRowIndex(options.index)}
|
||||||
{mode === CalculateFieldMode.UnaryOperation && this.renderUnaryOperation(options.unary)}
|
<InlineField labelWidth={labelWidth} label="Alias">
|
||||||
{mode === CalculateFieldMode.ReduceRow && this.renderReduceRow(options.reduce)}
|
<Input
|
||||||
{mode === CalculateFieldMode.CumulativeFunctions && this.renderCumulativeFunctions(options.cumulative)}
|
className="width-18"
|
||||||
{mode === CalculateFieldMode.WindowFunctions && this.renderWindowFunctions(options.window)}
|
value={options.alias ?? ''}
|
||||||
{mode === CalculateFieldMode.Index && this.renderRowIndex(options.index)}
|
placeholder={getNameFromOptions(options)}
|
||||||
<InlineField labelWidth={labelWidth} label="Alias">
|
onChange={onAliasChanged}
|
||||||
<Input
|
/>
|
||||||
className="width-18"
|
</InlineField>
|
||||||
value={options.alias ?? ''}
|
<InlineField labelWidth={labelWidth} label="Replace all fields">
|
||||||
placeholder={getNameFromOptions(options)}
|
<InlineSwitch value={!!options.replaceFields} onChange={onToggleReplaceFields} />
|
||||||
onChange={this.onAliasChanged}
|
</InlineField>
|
||||||
/>
|
</>
|
||||||
</InlineField>
|
);
|
||||||
<InlineField labelWidth={labelWidth} label="Replace all fields">
|
};
|
||||||
<InlineSwitch value={!!options.replaceFields} onChange={this.onToggleReplaceFields} />
|
|
||||||
</InlineField>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const calculateFieldTransformRegistryItem: TransformerRegistryItem<CalculateFieldTransformerOptions> = {
|
export const calculateFieldTransformRegistryItem: TransformerRegistryItem<CalculateFieldTransformerOptions> = {
|
||||||
id: DataTransformerID.calculateField,
|
id: DataTransformerID.calculateField,
|
||||||
|
Loading…
Reference in New Issue
Block a user