Files
Josh Hunt 3c6e0e8ef8 Chore: ESlint import order (#44959)
* Add and configure eslint-plugin-import

* Fix the lint:ts npm command

* Autofix + prettier all the files

* Manually fix remaining files

* Move jquery code in jest-setup to external file to safely reorder imports

* Resolve issue caused by circular dependencies within Prometheus

* Update .betterer.results

* Fix missing // @ts-ignore

* ignore iconBundle.ts

* Fix missing // @ts-ignore
2022-04-22 14:33:13 +01:00

62 lines
2.4 KiB
TypeScript

import { debounce } from 'lodash';
import React, { useCallback, useMemo } from 'react';
import { SelectableValue } from '@grafana/data';
import { SegmentAsync } from '@grafana/ui';
import { actions } from '../state/actions';
import { useDispatch } from '../state/context';
import { getAltSegmentsSelectables } from '../state/providers';
import { GraphiteQueryEditorState } from '../state/store';
import { GraphiteSegment } from '../types';
type Props = {
segment: GraphiteSegment;
metricIndex: number;
state: GraphiteQueryEditorState;
};
/**
* Represents a single metric node in the metric path at the given index. Allows to change the metric name to one of the
* provided options or a custom value.
*
* Options for tag names and metric names are reloaded while user is typing with backend taking care of auto-complete
* (auto-complete cannot be implemented in front-end because backend returns only limited number of entries)
*
* getAltSegmentsSelectables() also returns list of tags for segment with index=0. Once a tag is selected the editor
* enters tag-adding mode (see SeriesSection and GraphiteQueryModel.seriesByTagUsed).
*/
export function MetricSegment({ metricIndex, segment, state }: Props) {
const dispatch = useDispatch();
const loadOptions = useCallback(
(value: string | undefined) => {
return getAltSegmentsSelectables(state, metricIndex, value || '');
},
[state, metricIndex]
);
const debouncedLoadOptions = useMemo(() => debounce(loadOptions, 200, { leading: true }), [loadOptions]);
const onSegmentChanged = useCallback(
(selectableValue: SelectableValue<GraphiteSegment | string>) => {
// selectableValue.value is always defined because emptyValues are not allowed in SegmentAsync by default
dispatch(actions.segmentValueChanged({ segment: selectableValue.value!, index: metricIndex }));
},
[dispatch, metricIndex]
);
// segmentValueChanged action will destroy SegmentAsync immediately if a tag is selected. To give time
// for the clean up the action is debounced.
const onSegmentChangedDebounced = useMemo(() => debounce(onSegmentChanged, 100), [onSegmentChanged]);
return (
<SegmentAsync<GraphiteSegment | string>
value={segment.value}
inputMinWidth={150}
allowCustomValue={true}
loadOptions={debouncedLoadOptions}
reloadOptionsOnChange={true}
onChange={onSegmentChangedDebounced}
/>
);
}