mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Initial * WIP * wip * Refactor: fixing types * Refactor: Fixed more typings * Feature: Moves TestData to new API * Feature: Moves CloudMonitoringDatasource to new API * Feature: Moves PrometheusDatasource to new Variables API * Refactor: Clean up comments * Refactor: changes to QueryEditorProps instead * Refactor: cleans up testdata, prometheus and cloud monitoring variable support * Refactor: adds variableQueryRunner * Refactor: adds props to VariableQueryEditor * Refactor: reverted Loki editor * Refactor: refactor queryrunner into smaller pieces * Refactor: adds upgrade query thunk * Tests: Updates old tests * Docs: fixes build errors for exported api * Tests: adds guard tests * Tests: adds QueryRunner tests * Tests: fixes broken tests * Tests: adds variableQueryObserver tests * Test: adds tests for operator functions * Test: adds VariableQueryRunner tests * Refactor: renames dataSource * Refactor: adds definition for standard variable support * Refactor: adds cancellation to OptionPicker * Refactor: changes according to Dominiks suggestion * Refactor:tt * Refactor: adds tests for factories * Refactor: restructuring a bit * Refactor: renames variableQueryRunner.ts * Refactor: adds quick exit when runRequest returns errors * Refactor: using TextArea from grafana/ui * Refactor: changed from interfaces to classes instead * Tests: fixes broken test * Docs: fixes doc issue count * Docs: fixes doc issue count * Refactor: Adds check for self referencing queries * Tests: fixed unused variable * Refactor: Changes comments
141 lines
4.6 KiB
TypeScript
141 lines
4.6 KiB
TypeScript
import React, { PureComponent } from 'react';
|
|
import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux';
|
|
import { ClickOutsideWrapper } from '@grafana/ui';
|
|
import { LoadingState } from '@grafana/data';
|
|
|
|
import { StoreState } from 'app/types';
|
|
import { VariableLink } from '../shared/VariableLink';
|
|
import { VariableInput } from '../shared/VariableInput';
|
|
import { commitChangesToVariable, filterOrSearchOptions, navigateOptions, toggleAndFetchTag } from './actions';
|
|
import { OptionsPickerState, showOptions, toggleAllOptions, toggleOption } from './reducer';
|
|
import { VariableOption, VariableTag, VariableWithMultiSupport, VariableWithOptions } from '../../types';
|
|
import { VariableOptions } from '../shared/VariableOptions';
|
|
import { isQuery } from '../../guard';
|
|
import { VariablePickerProps } from '../types';
|
|
import { formatVariableLabel } from '../../shared/formatVariable';
|
|
import { toVariableIdentifier } from '../../state/types';
|
|
import { getVariableQueryRunner } from '../../query/VariableQueryRunner';
|
|
|
|
interface OwnProps extends VariablePickerProps<VariableWithMultiSupport> {}
|
|
|
|
interface ConnectedProps {
|
|
picker: OptionsPickerState;
|
|
}
|
|
|
|
interface DispatchProps {
|
|
showOptions: typeof showOptions;
|
|
commitChangesToVariable: typeof commitChangesToVariable;
|
|
toggleAllOptions: typeof toggleAllOptions;
|
|
toggleOption: typeof toggleOption;
|
|
toggleAndFetchTag: typeof toggleAndFetchTag;
|
|
filterOrSearchOptions: typeof filterOrSearchOptions;
|
|
navigateOptions: typeof navigateOptions;
|
|
}
|
|
|
|
type Props = OwnProps & ConnectedProps & DispatchProps;
|
|
|
|
export class OptionsPickerUnconnected extends PureComponent<Props> {
|
|
onShowOptions = () => this.props.showOptions(this.props.variable);
|
|
onHideOptions = () => this.props.commitChangesToVariable();
|
|
|
|
onToggleOption = (option: VariableOption, clearOthers: boolean) => {
|
|
const toggleFunc = this.props.variable.multi ? this.onToggleMultiValueVariable : this.onToggleSingleValueVariable;
|
|
toggleFunc(option, clearOthers);
|
|
};
|
|
|
|
onToggleSingleValueVariable = (option: VariableOption, clearOthers: boolean) => {
|
|
this.props.toggleOption({ option, clearOthers, forceSelect: false });
|
|
this.onHideOptions();
|
|
};
|
|
|
|
onToggleMultiValueVariable = (option: VariableOption, clearOthers: boolean) => {
|
|
this.props.toggleOption({ option, clearOthers, forceSelect: false });
|
|
};
|
|
|
|
render() {
|
|
const { variable, picker } = this.props;
|
|
const showOptions = picker.id === variable.id;
|
|
|
|
return (
|
|
<div className="variable-link-wrapper">
|
|
{this.renderLink(showOptions, variable)}
|
|
{this.renderOptions(showOptions, picker)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
renderLink(showOptions: boolean, variable: VariableWithMultiSupport) {
|
|
if (showOptions) {
|
|
return null;
|
|
}
|
|
|
|
const linkText = formatVariableLabel(variable);
|
|
const tags = getSelectedTags(variable);
|
|
const loading = variable.state === LoadingState.Loading;
|
|
|
|
return (
|
|
<VariableLink
|
|
text={linkText}
|
|
tags={tags}
|
|
onClick={this.onShowOptions}
|
|
loading={loading}
|
|
onCancel={this.onCancel}
|
|
/>
|
|
);
|
|
}
|
|
|
|
onCancel = () => {
|
|
getVariableQueryRunner().cancelRequest(toVariableIdentifier(this.props.variable));
|
|
};
|
|
|
|
renderOptions(showOptions: boolean, picker: OptionsPickerState) {
|
|
if (!showOptions) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<ClickOutsideWrapper onClick={this.onHideOptions}>
|
|
<VariableInput
|
|
value={picker.queryValue}
|
|
onChange={this.props.filterOrSearchOptions}
|
|
onNavigate={this.props.navigateOptions}
|
|
/>
|
|
<VariableOptions
|
|
values={picker.options}
|
|
onToggle={this.onToggleOption}
|
|
onToggleAll={this.props.toggleAllOptions}
|
|
onToggleTag={this.props.toggleAndFetchTag}
|
|
highlightIndex={picker.highlightIndex}
|
|
multi={picker.multi}
|
|
tags={picker.tags}
|
|
selectedValues={picker.selectedValues}
|
|
/>
|
|
</ClickOutsideWrapper>
|
|
);
|
|
}
|
|
}
|
|
|
|
const getSelectedTags = (variable: VariableWithOptions): VariableTag[] => {
|
|
if (!isQuery(variable) || !Array.isArray(variable.tags)) {
|
|
return [];
|
|
}
|
|
return variable.tags.filter(t => t.selected);
|
|
};
|
|
|
|
const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = {
|
|
showOptions,
|
|
commitChangesToVariable,
|
|
filterOrSearchOptions,
|
|
toggleAllOptions,
|
|
toggleOption,
|
|
toggleAndFetchTag,
|
|
navigateOptions,
|
|
};
|
|
|
|
const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = state => ({
|
|
picker: state.templating.optionsPicker,
|
|
});
|
|
|
|
export const OptionsPicker = connect(mapStateToProps, mapDispatchToProps)(OptionsPickerUnconnected);
|
|
OptionsPicker.displayName = 'OptionsPicker';
|