mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Pyroscope: Add Span ID to options collapsed info * Update for multiple * Update public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/QueryOptions.tsx Co-authored-by: Fabrizio <135109076+fabrizio-grafana@users.noreply.github.com> --------- Co-authored-by: Fabrizio <135109076+fabrizio-grafana@users.noreply.github.com>
141 lines
4.6 KiB
TypeScript
141 lines
4.6 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React from 'react';
|
|
|
|
import { CoreApp, GrafanaTheme2, SelectableValue } from '@grafana/data';
|
|
import { config } from '@grafana/runtime';
|
|
import { useStyles2, RadioButtonGroup, MultiSelect, Input } from '@grafana/ui';
|
|
|
|
import { QueryOptionGroup } from '../../prometheus/querybuilder/shared/QueryOptionGroup';
|
|
import { Query } from '../types';
|
|
|
|
import { EditorField } from './EditorField';
|
|
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.spanSelector?.length) {
|
|
collapsedInfo.push(`Span ID: ${query.spanSelector.join(', ')}`);
|
|
}
|
|
if (query.maxNodes) {
|
|
collapsedInfo.push(`Max nodes: ${query.maxNodes}`);
|
|
}
|
|
|
|
return (
|
|
<Stack gap={0} direction="column">
|
|
<QueryOptionGroup title="Options" collapsedInfo={collapsedInfo}>
|
|
<div className={styles.body}>
|
|
<EditorField label={'Query Type'}>
|
|
<RadioButtonGroup
|
|
options={typeOptions}
|
|
value={query.queryType}
|
|
onChange={(value) => onQueryChange({ ...query, queryType: value })}
|
|
/>
|
|
</EditorField>
|
|
<EditorField
|
|
label={'Group by'}
|
|
tooltip={
|
|
<>
|
|
Used to group the metric result by a specific label or set of labels. Does not apply to profile query.
|
|
</>
|
|
}
|
|
>
|
|
<MultiSelect
|
|
placeholder="Label"
|
|
value={query.groupBy}
|
|
allowCustomValue
|
|
options={groupByOptions}
|
|
onChange={(change) => {
|
|
const changes = change.map((c: SelectableValue<string>) => {
|
|
return c.value!;
|
|
});
|
|
onQueryChange({ ...query, groupBy: changes });
|
|
}}
|
|
/>
|
|
</EditorField>
|
|
{config.featureToggles.traceToProfiles && (
|
|
<EditorField label={'Span ID'} tooltip={<>Sets the span ID from which to search for profiles.</>}>
|
|
<Input
|
|
value={query.spanSelector || ['']}
|
|
type="string"
|
|
placeholder="64f170a95f537095"
|
|
onChange={(event: React.SyntheticEvent<HTMLInputElement>) => {
|
|
onQueryChange({
|
|
...query,
|
|
spanSelector: event.currentTarget.value !== '' ? [event.currentTarget.value] : [],
|
|
});
|
|
}}
|
|
/>
|
|
</EditorField>
|
|
)}
|
|
<EditorField label={'Max Nodes'} tooltip={<>Sets the maximum number of nodes to return in the flamegraph.</>}>
|
|
<Input
|
|
value={query.maxNodes || ''}
|
|
type="number"
|
|
placeholder="16384"
|
|
onChange={(event: React.SyntheticEvent<HTMLInputElement>) => {
|
|
let newValue = parseInt(event.currentTarget.value, 10);
|
|
newValue = isNaN(newValue) ? 0 : newValue;
|
|
onQueryChange({ ...query, maxNodes: newValue });
|
|
}}
|
|
/>
|
|
</EditorField>
|
|
</div>
|
|
</QueryOptionGroup>
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
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',
|
|
}),
|
|
};
|
|
};
|