Tempo: Option to not show variable options in "search" editor (#87126)
* allow disabling variable options in Tempo "search" editor * also for GroupByField * set addVariablesToOptions true by default
This commit is contained in:
@@ -23,7 +23,10 @@ import { QueryEditor } from './traceql/QueryEditor';
|
||||
import { TempoQuery } from './types';
|
||||
import { migrateFromSearchToTraceQLSearch } from './utils';
|
||||
|
||||
interface Props extends QueryEditorProps<TempoDatasource, TempoQuery>, Themeable2 {}
|
||||
interface Props extends QueryEditorProps<TempoDatasource, TempoQuery>, Themeable2 {
|
||||
// should template variables be added to tag options. default true
|
||||
addVariablesToOptions?: boolean;
|
||||
}
|
||||
interface State {
|
||||
uploadModalOpen: boolean;
|
||||
}
|
||||
@@ -154,6 +157,7 @@ class TempoQueryFieldComponent extends React.PureComponent<Props, State> {
|
||||
onBlur={this.props.onBlur}
|
||||
app={app}
|
||||
onClearResults={this.onClearResults}
|
||||
addVariablesToOptions={this.props.addVariablesToOptions}
|
||||
/>
|
||||
)}
|
||||
{query.queryType === 'serviceMap' && (
|
||||
|
||||
@@ -138,7 +138,13 @@ describe('GroupByField', () => {
|
||||
|
||||
it('should allow selecting template variables', async () => {
|
||||
const { container } = render(
|
||||
<GroupByField datasource={datasource} query={query} onChange={onChange} isTagsLoading={false} />
|
||||
<GroupByField
|
||||
datasource={datasource}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
isTagsLoading={false}
|
||||
addVariablesToOptions={true}
|
||||
/>
|
||||
);
|
||||
|
||||
const tagSelect = container.querySelector(`input[aria-label="Select tag for filter 1"]`);
|
||||
|
||||
@@ -19,10 +19,11 @@ interface Props {
|
||||
onChange: (value: TempoQuery) => void;
|
||||
query: Partial<TempoQuery> & TempoQuery;
|
||||
isTagsLoading: boolean;
|
||||
addVariablesToOptions?: boolean;
|
||||
}
|
||||
|
||||
export const GroupByField = (props: Props) => {
|
||||
const { datasource, onChange, query, isTagsLoading } = props;
|
||||
const { datasource, onChange, query, isTagsLoading, addVariablesToOptions } = props;
|
||||
const styles = useStyles2(getStyles);
|
||||
const generateId = () => uuidv4().slice(0, 8);
|
||||
|
||||
@@ -75,62 +76,63 @@ export const GroupByField = (props: Props) => {
|
||||
tooltip="Select one or more tags to see the metrics summary. Note: the metrics summary API only considers spans of kind = server."
|
||||
>
|
||||
<>
|
||||
{query.groupBy?.map((f, i) => (
|
||||
<div key={f.id}>
|
||||
<HorizontalGroup spacing={'none'} width={'auto'}>
|
||||
<Select
|
||||
aria-label={`Select scope for filter ${i + 1}`}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...f, scope: v?.value, tag: '' });
|
||||
}}
|
||||
options={scopeOptions}
|
||||
placeholder="Select scope"
|
||||
value={f.scope}
|
||||
/>
|
||||
<Select
|
||||
aria-label={`Select tag for filter ${i + 1}`}
|
||||
isClearable
|
||||
allowCustomValue
|
||||
isLoading={isTagsLoading}
|
||||
key={f.tag}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...f, tag: v?.value });
|
||||
}}
|
||||
options={withTemplateVariableOptions(
|
||||
getTags(f)
|
||||
?.concat(f.tag !== undefined && !getTags(f)?.includes(f.tag) ? [f.tag] : [])
|
||||
.map((t) => ({
|
||||
label: t,
|
||||
value: t,
|
||||
}))
|
||||
)}
|
||||
placeholder="Select tag"
|
||||
value={f.tag || ''}
|
||||
/>
|
||||
{(f.tag || (query.groupBy?.length ?? 0) > 1) && (
|
||||
<AccessoryButton
|
||||
aria-label={`Remove tag for filter ${i + 1}`}
|
||||
icon="times"
|
||||
onClick={() => removeFilter(f)}
|
||||
tooltip="Remove tag"
|
||||
title={`Remove tag for filter ${i + 1}`}
|
||||
variant="secondary"
|
||||
{query.groupBy?.map((f, i) => {
|
||||
const tags = getTags(f)
|
||||
?.concat(f.tag !== undefined && !getTags(f)?.includes(f.tag) ? [f.tag] : [])
|
||||
.map((t) => ({
|
||||
label: t,
|
||||
value: t,
|
||||
}));
|
||||
return (
|
||||
<div key={f.id}>
|
||||
<HorizontalGroup spacing={'none'} width={'auto'}>
|
||||
<Select
|
||||
aria-label={`Select scope for filter ${i + 1}`}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...f, scope: v?.value, tag: '' });
|
||||
}}
|
||||
options={scopeOptions}
|
||||
placeholder="Select scope"
|
||||
value={f.scope}
|
||||
/>
|
||||
)}
|
||||
{f.tag && i === (query.groupBy?.length ?? 0) - 1 && (
|
||||
<span className={styles.addTag}>
|
||||
<Select
|
||||
aria-label={`Select tag for filter ${i + 1}`}
|
||||
isClearable
|
||||
allowCustomValue
|
||||
isLoading={isTagsLoading}
|
||||
key={f.tag}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...f, tag: v?.value });
|
||||
}}
|
||||
options={addVariablesToOptions ? withTemplateVariableOptions(tags) : tags}
|
||||
placeholder="Select tag"
|
||||
value={f.tag || ''}
|
||||
/>
|
||||
{(f.tag || (query.groupBy?.length ?? 0) > 1) && (
|
||||
<AccessoryButton
|
||||
aria-label="Add tag"
|
||||
icon="plus"
|
||||
onClick={() => addFilter()}
|
||||
tooltip="Add tag"
|
||||
aria-label={`Remove tag for filter ${i + 1}`}
|
||||
icon="times"
|
||||
onClick={() => removeFilter(f)}
|
||||
tooltip="Remove tag"
|
||||
title={`Remove tag for filter ${i + 1}`}
|
||||
variant="secondary"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
))}
|
||||
)}
|
||||
{f.tag && i === (query.groupBy?.length ?? 0) - 1 && (
|
||||
<span className={styles.addTag}>
|
||||
<AccessoryButton
|
||||
aria-label="Add tag"
|
||||
icon="plus"
|
||||
onClick={() => addFilter()}
|
||||
tooltip="Add tag"
|
||||
variant="secondary"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
</InlineSearchField>
|
||||
);
|
||||
|
||||
@@ -293,6 +293,7 @@ const renderSearchField = (
|
||||
tags={tags || []}
|
||||
hideTag={hideTag}
|
||||
query={'{}'}
|
||||
addVariablesToOptions={true}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@ interface Props {
|
||||
query: string;
|
||||
isMulti?: boolean;
|
||||
allowCustomValue?: boolean;
|
||||
addVariablesToOptions?: boolean;
|
||||
}
|
||||
const SearchField = ({
|
||||
filter,
|
||||
@@ -46,6 +47,7 @@ const SearchField = ({
|
||||
hideTag,
|
||||
hideValue,
|
||||
query,
|
||||
addVariablesToOptions,
|
||||
isMulti = true,
|
||||
allowCustomValue = true,
|
||||
}: Props) => {
|
||||
@@ -126,6 +128,13 @@ const SearchField = ({
|
||||
operatorList = numberOperators;
|
||||
}
|
||||
|
||||
const tagOptions = (filter.tag !== undefined ? uniq([filter.tag, ...tags]) : tags).map((t) => ({
|
||||
label: t,
|
||||
value: t,
|
||||
}));
|
||||
|
||||
const operatorOptions = operatorList.map(operatorSelectableValue);
|
||||
|
||||
return (
|
||||
<>
|
||||
<HorizontalGroup spacing={'none'} width={'auto'}>
|
||||
@@ -133,7 +142,7 @@ const SearchField = ({
|
||||
<Select
|
||||
className={styles.dropdown}
|
||||
inputId={`${filter.id}-scope`}
|
||||
options={withTemplateVariableOptions(scopeOptions)}
|
||||
options={addVariablesToOptions ? withTemplateVariableOptions(scopeOptions) : scopeOptions}
|
||||
value={filter.scope}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...filter, scope: v?.value });
|
||||
@@ -148,12 +157,7 @@ const SearchField = ({
|
||||
inputId={`${filter.id}-tag`}
|
||||
isLoading={isTagsLoading}
|
||||
// Add the current tag to the list if it doesn't exist in the tags prop, otherwise the field will be empty even though the state has a value
|
||||
options={withTemplateVariableOptions(
|
||||
(filter.tag !== undefined ? uniq([filter.tag, ...tags]) : tags).map((t) => ({
|
||||
label: t,
|
||||
value: t,
|
||||
}))
|
||||
)}
|
||||
options={addVariablesToOptions ? withTemplateVariableOptions(tagOptions) : tagOptions}
|
||||
value={filter.tag}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...filter, tag: v?.value, value: [] });
|
||||
@@ -167,7 +171,7 @@ const SearchField = ({
|
||||
<Select
|
||||
className={styles.dropdown}
|
||||
inputId={`${filter.id}-operator`}
|
||||
options={withTemplateVariableOptions(operatorList.map(operatorSelectableValue))}
|
||||
options={addVariablesToOptions ? withTemplateVariableOptions(operatorOptions) : operatorOptions}
|
||||
value={filter.operator}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...filter, operator: v?.value });
|
||||
@@ -182,7 +186,7 @@ const SearchField = ({
|
||||
className={styles.dropdown}
|
||||
inputId={`${filter.id}-value`}
|
||||
isLoading={isLoadingValues}
|
||||
options={withTemplateVariableOptions(options)}
|
||||
options={addVariablesToOptions ? withTemplateVariableOptions(options) : options}
|
||||
value={filter.value}
|
||||
onChange={(val) => {
|
||||
if (Array.isArray(val)) {
|
||||
|
||||
@@ -126,6 +126,7 @@ describe('TagsInput', () => {
|
||||
staticTags={[]}
|
||||
isTagsLoading={false}
|
||||
query={''}
|
||||
addVariablesToOptions={true}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@ interface Props {
|
||||
hideValues?: boolean;
|
||||
requireTagAndValue?: boolean;
|
||||
query: string;
|
||||
addVariablesToOptions?: boolean;
|
||||
}
|
||||
const TagsInput = ({
|
||||
updateFilter,
|
||||
@@ -52,6 +53,7 @@ const TagsInput = ({
|
||||
hideValues,
|
||||
requireTagAndValue,
|
||||
query,
|
||||
addVariablesToOptions,
|
||||
}: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const handleOnAdd = useCallback(
|
||||
@@ -88,6 +90,7 @@ const TagsInput = ({
|
||||
isTagsLoading={isTagsLoading}
|
||||
hideValue={hideValues}
|
||||
query={query}
|
||||
addVariablesToOptions={addVariablesToOptions}
|
||||
/>
|
||||
{(validInput(f) || filters.length > 1) && (
|
||||
<AccessoryButton
|
||||
|
||||
@@ -27,11 +27,12 @@ interface Props {
|
||||
onBlur?: () => void;
|
||||
onClearResults: () => void;
|
||||
app?: CoreApp;
|
||||
addVariablesToOptions?: boolean;
|
||||
}
|
||||
|
||||
const hardCodedFilterIds = ['min-duration', 'max-duration', 'status'];
|
||||
|
||||
const TraceQLSearch = ({ datasource, query, onChange, onClearResults, app }: Props) => {
|
||||
const TraceQLSearch = ({ datasource, query, onChange, onClearResults, app, addVariablesToOptions = true }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const [alertText, setAlertText] = useState<string>();
|
||||
const [error, setError] = useState<Error | FetchError | null>(null);
|
||||
@@ -130,6 +131,7 @@ const TraceQLSearch = ({ datasource, query, onChange, onClearResults, app }: Pro
|
||||
hideScope={true}
|
||||
hideTag={true}
|
||||
query={traceQlQuery}
|
||||
addVariablesToOptions={addVariablesToOptions}
|
||||
/>
|
||||
</InlineSearchField>
|
||||
)
|
||||
@@ -153,6 +155,7 @@ const TraceQLSearch = ({ datasource, query, onChange, onClearResults, app }: Pro
|
||||
query={traceQlQuery}
|
||||
isMulti={false}
|
||||
allowCustomValue={false}
|
||||
addVariablesToOptions={addVariablesToOptions}
|
||||
/>
|
||||
</InlineSearchField>
|
||||
<InlineSearchField
|
||||
@@ -212,10 +215,17 @@ const TraceQLSearch = ({ datasource, query, onChange, onClearResults, app }: Pro
|
||||
isTagsLoading={isTagsLoading}
|
||||
query={traceQlQuery}
|
||||
requireTagAndValue={true}
|
||||
addVariablesToOptions={addVariablesToOptions}
|
||||
/>
|
||||
</InlineSearchField>
|
||||
{config.featureToggles.metricsSummary && (
|
||||
<GroupByField datasource={datasource} onChange={onChange} query={query} isTagsLoading={isTagsLoading} />
|
||||
<GroupByField
|
||||
datasource={datasource}
|
||||
onChange={onChange}
|
||||
query={query}
|
||||
isTagsLoading={isTagsLoading}
|
||||
addVariablesToOptions={addVariablesToOptions}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.rawQueryContainer}>
|
||||
|
||||
Reference in New Issue
Block a user