import { css } from '@emotion/css'; import * as React from 'react'; import { CoreApp, GrafanaTheme2, SelectableValue } from '@grafana/data'; import { useStyles2, RadioButtonGroup, MultiSelect, Input } from '@grafana/ui'; import { Query } from '../types'; import { EditorField } from './EditorField'; import { QueryOptionGroup } from './QueryOptionGroup'; import { Stack } from './Stack'; export interface Props { query: Query; onQueryChange: (query: Query) => void; app?: CoreApp; labels?: string[]; } const typeOptions: Array<{ value: Query['queryType']; label: string; description: string }> = [ { value: 'metrics', label: 'Metric', description: 'Return aggregated metrics' }, { value: 'profile', label: 'Profile', description: 'Return profile' }, { value: 'both', label: 'Both', description: 'Return both metric and profile data' }, ]; function getTypeOptions(app?: CoreApp) { if (app === CoreApp.Explore) { return typeOptions; } return typeOptions.filter((option) => option.value !== 'both'); } /** * Base on QueryOptionGroup component from grafana/ui but that is not available yet. */ export function QueryOptions({ query, onQueryChange, app, labels }: Props) { const styles = useStyles2(getStyles); const typeOptions = getTypeOptions(app); const groupByOptions = labels ? labels.map((l) => ({ label: l, value: l, })) : []; let collapsedInfo = [`Type: ${query.queryType}`]; if (query.groupBy?.length) { collapsedInfo.push(`Group by: ${query.groupBy.join(', ')}`); } if (query.limit) { collapsedInfo.push(`Limit: ${query.limit}`); } if (query.spanSelector?.length) { collapsedInfo.push(`Span ID: ${query.spanSelector.join(', ')}`); } if (query.maxNodes) { collapsedInfo.push(`Max nodes: ${query.maxNodes}`); } return (
onQueryChange({ ...query, queryType: value })} /> Used to group the metric result by a specific label or set of labels. Does not apply to profile query. } > { const changes = change.map((c: SelectableValue) => { return c.value!; }); onQueryChange({ ...query, groupBy: changes }); }} /> When "Group by" is set, limits the maximum number of series to return. Does not apply to profile query. } > ) => { let newValue = parseInt(event.currentTarget.value, 10); newValue = isNaN(newValue) ? 0 : newValue; onQueryChange({ ...query, limit: newValue }); }} /> Sets the span ID from which to search for profiles.}> ) => { onQueryChange({ ...query, spanSelector: event.currentTarget.value !== '' ? [event.currentTarget.value] : [], }); }} /> Sets the maximum number of nodes to return in the flamegraph.}> ) => { let newValue = parseInt(event.currentTarget.value, 10); newValue = isNaN(newValue) ? 0 : newValue; onQueryChange({ ...query, maxNodes: newValue }); }} />
); } const getStyles = (theme: GrafanaTheme2) => { return { switchLabel: css({ color: theme.colors.text.secondary, cursor: 'pointer', fontSize: theme.typography.bodySmall.fontSize, '&:hover': { color: theme.colors.text.primary, }, }), body: css({ display: 'flex', paddingTop: theme.spacing(2), gap: theme.spacing(2), flexWrap: 'wrap', }), }; };