import React, { PureComponent, ReactNode } from 'react'; import { connect, MapDispatchToProps, MapStateToProps } from 'react-redux'; import { StoreState } from 'app/types'; import { AdHocVariableFilter, AdHocVariableModel } from 'app/features/variables/types'; import { SegmentAsync } from '@grafana/ui'; import { VariablePickerProps } from '../../pickers/types'; import { OperatorSegment } from './OperatorSegment'; import { MetricFindValue, SelectableValue } from '@grafana/data'; import { AdHocFilterBuilder } from './AdHocFilterBuilder'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { ConditionSegment } from './ConditionSegment'; import { addFilter, changeFilter, removeFilter } from '../actions'; interface OwnProps extends VariablePickerProps {} interface ConnectedProps {} interface DispatchProps { addFilter: typeof addFilter; removeFilter: typeof removeFilter; changeFilter: typeof changeFilter; } type Props = OwnProps & ConnectedProps & DispatchProps; const REMOVE_FILTER_KEY = '-- remove filter --'; const REMOVE_VALUE = { label: REMOVE_FILTER_KEY, value: REMOVE_FILTER_KEY }; export class AdHocPickerUnconnected extends PureComponent { onChange = (index: number, prop: string) => (key: SelectableValue) => { const { id, filters } = this.props.variable; const { value } = key; if (key.value === REMOVE_FILTER_KEY) { return this.props.removeFilter(id, index); } return this.props.changeFilter(id, { index, filter: { ...filters[index], [prop]: value, }, }); }; appendFilterToVariable = (filter: AdHocVariableFilter) => { const { id } = this.props.variable; this.props.addFilter(id, filter); }; fetchFilterKeys = async () => { const { variable } = this.props; const ds = await getDatasourceSrv().get(variable.datasource!); if (!ds || !ds.getTagKeys) { return []; } const metrics = await ds.getTagKeys(); return metrics.map(m => ({ label: m.text, value: m.text })); }; fetchFilterKeysWithRemove = async () => { const keys = await this.fetchFilterKeys(); return [REMOVE_VALUE, ...keys]; }; fetchFilterValues = async (key: string) => { const { variable } = this.props; const ds = await getDatasourceSrv().get(variable.datasource!); if (!ds || !ds.getTagValues) { return []; } const metrics = await ds.getTagValues({ key }); return metrics.map((m: MetricFindValue) => ({ label: m.text, value: m.text })); }; render() { const { filters } = this.props.variable; return (
{this.renderFilters(filters)} 0 ? : null} onLoadKeys={this.fetchFilterKeys} onLoadValues={this.fetchFilterValues} onCompleted={this.appendFilterToVariable} />
); } renderFilters(filters: AdHocVariableFilter[]) { return filters.reduce((segments: ReactNode[], filter, index) => { if (segments.length > 0) { segments.push(); } segments.push(this.renderFilterSegments(filter, index)); return segments; }, []); } renderFilterSegments(filter: AdHocVariableFilter, index: number) { return (
this.fetchFilterValues(filter.key)} />
); } } const mapDispatchToProps: MapDispatchToProps = { addFilter, removeFilter, changeFilter, }; const mapStateToProps: MapStateToProps = state => ({}); export const AdHocPicker = connect(mapStateToProps, mapDispatchToProps)(AdHocPickerUnconnected); AdHocPicker.displayName = 'AdHocPicker';