mirror of
https://github.com/grafana/grafana.git
synced 2025-01-16 03:32:37 -06:00
a9d44aa795
+Cloudwatch implementation
242 lines
7.9 KiB
TypeScript
242 lines
7.9 KiB
TypeScript
import React, { FormEvent, PureComponent } from 'react';
|
|
import { connect, ConnectedProps } from 'react-redux';
|
|
|
|
import { DataSourceInstanceSettings, getDataSourceRef, LoadingState, SelectableValue } from '@grafana/data';
|
|
import { selectors } from '@grafana/e2e-selectors';
|
|
import { DataSourcePicker, getTemplateSrv } from '@grafana/runtime';
|
|
import { Field } from '@grafana/ui';
|
|
|
|
import { StoreState } from '../../../types';
|
|
import { getTimeSrv } from '../../dashboard/services/TimeSrv';
|
|
import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor';
|
|
import { VariableLegend } from '../editor/VariableLegend';
|
|
import { VariableTextAreaField } from '../editor/VariableTextAreaField';
|
|
import { initialVariableEditorState } from '../editor/reducer';
|
|
import { getQueryVariableEditorState } from '../editor/selectors';
|
|
import { OnPropChangeArguments, VariableEditorProps } from '../editor/types';
|
|
import { isLegacyQueryEditor, isQueryEditor } from '../guard';
|
|
import { changeVariableMultiValue } from '../state/actions';
|
|
import { getVariablesState } from '../state/selectors';
|
|
import { QueryVariableModel, VariableRefresh, VariableSort, VariableWithMultiSupport } from '../types';
|
|
import { toKeyedVariableIdentifier } from '../utils';
|
|
|
|
import { QueryVariableRefreshSelect } from './QueryVariableRefreshSelect';
|
|
import { QueryVariableSortSelect } from './QueryVariableSortSelect';
|
|
import { changeQueryVariableDataSource, changeQueryVariableQuery, initQueryVariableEditor } from './actions';
|
|
|
|
const mapStateToProps = (state: StoreState, ownProps: OwnProps) => {
|
|
const { rootStateKey } = ownProps.variable;
|
|
if (!rootStateKey) {
|
|
console.error('QueryVariableEditor: variable has no rootStateKey');
|
|
return {
|
|
extended: getQueryVariableEditorState(initialVariableEditorState),
|
|
};
|
|
}
|
|
|
|
const { editor } = getVariablesState(rootStateKey, state);
|
|
|
|
return {
|
|
extended: getQueryVariableEditorState(editor),
|
|
};
|
|
};
|
|
|
|
const mapDispatchToProps = {
|
|
initQueryVariableEditor,
|
|
changeQueryVariableDataSource,
|
|
changeQueryVariableQuery,
|
|
changeVariableMultiValue,
|
|
};
|
|
|
|
const connector = connect(mapStateToProps, mapDispatchToProps);
|
|
|
|
export interface OwnProps extends VariableEditorProps<QueryVariableModel> {}
|
|
|
|
export type Props = OwnProps & ConnectedProps<typeof connector>;
|
|
|
|
export interface State {
|
|
regex: string | null;
|
|
tagsQuery: string | null;
|
|
tagValuesQuery: string | null;
|
|
}
|
|
|
|
export class QueryVariableEditorUnConnected extends PureComponent<Props, State> {
|
|
state: State = {
|
|
regex: null,
|
|
tagsQuery: null,
|
|
tagValuesQuery: null,
|
|
};
|
|
|
|
async componentDidMount() {
|
|
await this.props.initQueryVariableEditor(toKeyedVariableIdentifier(this.props.variable));
|
|
}
|
|
|
|
componentDidUpdate(prevProps: Readonly<Props>): void {
|
|
if (prevProps.variable.datasource !== this.props.variable.datasource) {
|
|
this.props.changeQueryVariableDataSource(
|
|
toKeyedVariableIdentifier(this.props.variable),
|
|
this.props.variable.datasource
|
|
);
|
|
}
|
|
}
|
|
|
|
onDataSourceChange = (dsSettings: DataSourceInstanceSettings) => {
|
|
this.props.onPropChange({
|
|
propName: 'datasource',
|
|
propValue: dsSettings.isDefault ? null : getDataSourceRef(dsSettings),
|
|
});
|
|
};
|
|
|
|
onLegacyQueryChange = async (query: any, definition: string) => {
|
|
if (this.props.variable.query !== query) {
|
|
this.props.changeQueryVariableQuery(toKeyedVariableIdentifier(this.props.variable), query, definition);
|
|
}
|
|
};
|
|
|
|
onQueryChange = async (query: any) => {
|
|
if (this.props.variable.query !== query) {
|
|
let definition = '';
|
|
|
|
if (query && query.hasOwnProperty('query') && typeof query.query === 'string') {
|
|
definition = query.query;
|
|
}
|
|
|
|
this.props.changeQueryVariableQuery(toKeyedVariableIdentifier(this.props.variable), query, definition);
|
|
}
|
|
};
|
|
|
|
onRegExChange = (event: FormEvent<HTMLTextAreaElement>) => {
|
|
this.setState({ regex: event.currentTarget.value });
|
|
};
|
|
|
|
onRegExBlur = async (event: FormEvent<HTMLTextAreaElement>) => {
|
|
const regex = event.currentTarget.value;
|
|
if (this.props.variable.regex !== regex) {
|
|
this.props.onPropChange({ propName: 'regex', propValue: regex, updateOptions: true });
|
|
}
|
|
};
|
|
|
|
onRefreshChange = (option: VariableRefresh) => {
|
|
this.props.onPropChange({ propName: 'refresh', propValue: option });
|
|
};
|
|
|
|
onSortChange = async (option: SelectableValue<VariableSort>) => {
|
|
this.props.onPropChange({ propName: 'sort', propValue: option.value, updateOptions: true });
|
|
};
|
|
|
|
onSelectionOptionsChange = async ({ propValue, propName }: OnPropChangeArguments<VariableWithMultiSupport>) => {
|
|
this.props.onPropChange({ propName, propValue, updateOptions: true });
|
|
};
|
|
|
|
renderQueryEditor = () => {
|
|
const { extended, variable } = this.props;
|
|
|
|
if (!extended || !extended.dataSource || !extended.VariableQueryEditor) {
|
|
return null;
|
|
}
|
|
|
|
const datasource = extended.dataSource;
|
|
const VariableQueryEditor = extended.VariableQueryEditor;
|
|
|
|
let query = variable.query;
|
|
|
|
if (typeof query === 'string') {
|
|
query = query || (datasource.variables?.getDefaultQuery?.() ?? '');
|
|
} else {
|
|
query = {
|
|
...datasource.variables?.getDefaultQuery?.(),
|
|
...variable.query,
|
|
};
|
|
}
|
|
|
|
if (isLegacyQueryEditor(VariableQueryEditor, datasource)) {
|
|
return (
|
|
<Field label="Query">
|
|
<VariableQueryEditor
|
|
datasource={datasource}
|
|
query={query}
|
|
templateSrv={getTemplateSrv()}
|
|
onChange={this.onLegacyQueryChange}
|
|
/>
|
|
</Field>
|
|
);
|
|
}
|
|
|
|
const range = getTimeSrv().timeRange();
|
|
|
|
if (isQueryEditor(VariableQueryEditor, datasource)) {
|
|
return (
|
|
<Field label="Query">
|
|
<VariableQueryEditor
|
|
datasource={datasource}
|
|
query={query}
|
|
onChange={this.onQueryChange}
|
|
onRunQuery={() => {}}
|
|
data={{ series: [], state: LoadingState.Done, timeRange: range }}
|
|
range={range}
|
|
onBlur={() => {}}
|
|
history={[]}
|
|
/>
|
|
</Field>
|
|
);
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<>
|
|
<VariableLegend>Query options</VariableLegend>
|
|
<Field label="Data source" htmlFor="data-source-picker">
|
|
<DataSourcePicker
|
|
current={this.props.variable.datasource}
|
|
onChange={this.onDataSourceChange}
|
|
variables={true}
|
|
width={30}
|
|
/>
|
|
</Field>
|
|
|
|
{this.renderQueryEditor()}
|
|
|
|
<VariableTextAreaField
|
|
value={this.state.regex ?? this.props.variable.regex}
|
|
name="Regex"
|
|
description={
|
|
<div>
|
|
Optional, if you want to extract part of a series name or metric node segment.
|
|
<br />
|
|
Named capture groups can be used to separate the display text and value (
|
|
<a
|
|
className="external-link"
|
|
href="https://grafana.com/docs/grafana/latest/variables/filter-variables-with-regex#filter-and-modify-using-named-text-and-value-capture-groups"
|
|
target="__blank"
|
|
>
|
|
see examples
|
|
</a>
|
|
).
|
|
</div>
|
|
}
|
|
placeholder="/.*-(?<text>.*)-(?<value>.*)-.*/"
|
|
onChange={this.onRegExChange}
|
|
onBlur={this.onRegExBlur}
|
|
testId={selectors.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExInputV2}
|
|
width={52}
|
|
/>
|
|
|
|
<QueryVariableSortSelect onChange={this.onSortChange} sort={this.props.variable.sort} />
|
|
|
|
<QueryVariableRefreshSelect onChange={this.onRefreshChange} refresh={this.props.variable.refresh} />
|
|
|
|
<VariableLegend>Selection options</VariableLegend>
|
|
<SelectionOptionsEditor
|
|
variable={this.props.variable}
|
|
onPropChange={this.onSelectionOptionsChange}
|
|
onMultiChanged={this.props.changeVariableMultiValue}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
}
|
|
|
|
export const QueryVariableEditor = connector(QueryVariableEditorUnConnected);
|