1import React, { FunctionComponent, useMemo } from 'react';
2import { SelectableValue } from '@grafana/data';
3import { MultiSelect } from '@grafana/ui';
4import { labelsToGroupedOptions } from '../functions';
5import { SYSTEM_LABELS, INPUT_WIDTH } from '../constants';
6import { MetricDescriptor, MetricQuery } from '../types';
7import { Aggregation, QueryEditorRow } from '.';
8
9export interface Props {
10  variableOptionGroup: SelectableValue<string>;
11  labels: string[];
12  metricDescriptor?: MetricDescriptor;
13  onChange: (query: MetricQuery) => void;
14  query: MetricQuery;
15}
16
17export const GroupBy: FunctionComponent<Props> = ({
18  labels: groupBys = [],
19  query,
20  onChange,
21  variableOptionGroup,
22  metricDescriptor,
23}) => {
24  const options = useMemo(() => [variableOptionGroup, ...labelsToGroupedOptions([...groupBys, ...SYSTEM_LABELS])], [
25    groupBys,
26    variableOptionGroup,
27  ]);
28
29  return (
30    <QueryEditorRow
31      label="Group by"
32      tooltip="You can reduce the amount of data returned for a metric by combining different time series. To combine multiple time series, you can specify a grouping and a function. Grouping is done on the basis of labels. The grouping function is used to combine the time series in the group into a single time series."
33    >
34      <MultiSelect
35        menuShouldPortal
36        width={INPUT_WIDTH}
37        placeholder="Choose label"
38        options={options}
39        value={query.groupBys ?? []}
40        onChange={(options) => {
41          onChange({ ...query, groupBys: options.map((o) => o.value!) });
42        }}
43      ></MultiSelect>
44      <Aggregation
45        metricDescriptor={metricDescriptor}
46        templateVariableOptions={variableOptionGroup.options}
47        crossSeriesReducer={query.crossSeriesReducer}
48        groupBys={query.groupBys ?? []}
49        onChange={(crossSeriesReducer) => onChange({ ...query, crossSeriesReducer })}
50      ></Aggregation>
51    </QueryEditorRow>
52  );
53};
54