mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Influxdb: Improve filtering (#60994)
* Add createOptionPosition props to SelectBase * Show create option in the beginning of the list * Show only matched template variables * Fix the test * Remove redundant check
This commit is contained in:
parent
e0c7ef3481
commit
6a68fbb495
@ -97,6 +97,7 @@ export function SelectBase<T>({
|
|||||||
className,
|
className,
|
||||||
closeMenuOnSelect = true,
|
closeMenuOnSelect = true,
|
||||||
components,
|
components,
|
||||||
|
createOptionPosition = 'last',
|
||||||
defaultOptions,
|
defaultOptions,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
@ -256,6 +257,7 @@ export function SelectBase<T>({
|
|||||||
creatableProps.allowCreateWhileLoading = allowCreateWhileLoading;
|
creatableProps.allowCreateWhileLoading = allowCreateWhileLoading;
|
||||||
creatableProps.formatCreateLabel = formatCreateLabel ?? defaultFormatCreateLabel;
|
creatableProps.formatCreateLabel = formatCreateLabel ?? defaultFormatCreateLabel;
|
||||||
creatableProps.onCreateOption = onCreateOption;
|
creatableProps.onCreateOption = onCreateOption;
|
||||||
|
creatableProps.createOptionPosition = createOptionPosition;
|
||||||
creatableProps.isValidNewOption = isValidNewOption;
|
creatableProps.isValidNewOption = isValidNewOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ export interface SelectCommonProps<T> {
|
|||||||
closeMenuOnSelect?: boolean;
|
closeMenuOnSelect?: boolean;
|
||||||
/** Used for custom components. For more information, see `react-select` */
|
/** Used for custom components. For more information, see `react-select` */
|
||||||
components?: any;
|
components?: any;
|
||||||
|
/** Sets the position of the createOption element in your options list. Defaults to 'last' */
|
||||||
|
createOptionPosition?: 'first' | 'last';
|
||||||
defaultValue?: any;
|
defaultValue?: any;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
filterOption?: (option: SelectableValue<T>, searchQuery: string) => boolean;
|
filterOption?: (option: SelectableValue<T>, searchQuery: string) => boolean;
|
||||||
@ -140,6 +142,7 @@ export type ControlComponent<T> = React.ComponentType<CustomControlProps<T>>;
|
|||||||
export interface SelectableOptGroup<T = any> {
|
export interface SelectableOptGroup<T = any> {
|
||||||
label: string;
|
label: string;
|
||||||
options: Array<SelectableValue<T>>;
|
options: Array<SelectableValue<T>>;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,14 @@ jest.mock('../../influxQLMetadataQuery', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('@grafana/runtime', () => {
|
||||||
|
return {
|
||||||
|
getTemplateSrv: jest.fn().mockReturnValueOnce({
|
||||||
|
getVariables: jest.fn().mockReturnValueOnce([]),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(mockedMeta.getTagKeysForMeasurementAndTags as jest.Mock).mockClear();
|
(mockedMeta.getTagKeysForMeasurementAndTags as jest.Mock).mockClear();
|
||||||
});
|
});
|
||||||
|
@ -14,13 +14,13 @@ import {
|
|||||||
getTagValues,
|
getTagValues,
|
||||||
} from '../../influxQLMetadataQuery';
|
} from '../../influxQLMetadataQuery';
|
||||||
import {
|
import {
|
||||||
normalizeQuery,
|
|
||||||
addNewSelectPart,
|
|
||||||
removeSelectPart,
|
|
||||||
addNewGroupByPart,
|
addNewGroupByPart,
|
||||||
removeGroupByPart,
|
addNewSelectPart,
|
||||||
changeSelectPart,
|
|
||||||
changeGroupByPart,
|
changeGroupByPart,
|
||||||
|
changeSelectPart,
|
||||||
|
normalizeQuery,
|
||||||
|
removeGroupByPart,
|
||||||
|
removeSelectPart,
|
||||||
} from '../../queryUtils';
|
} from '../../queryUtils';
|
||||||
import { InfluxQuery, InfluxQueryTag } from '../../types';
|
import { InfluxQuery, InfluxQueryTag } from '../../types';
|
||||||
import { DEFAULT_RESULT_FORMAT } from '../constants';
|
import { DEFAULT_RESULT_FORMAT } from '../constants';
|
||||||
@ -32,7 +32,7 @@ import { InputSection } from './InputSection';
|
|||||||
import { OrderByTimeSection } from './OrderByTimeSection';
|
import { OrderByTimeSection } from './OrderByTimeSection';
|
||||||
import { PartListSection } from './PartListSection';
|
import { PartListSection } from './PartListSection';
|
||||||
import { TagsSection } from './TagsSection';
|
import { TagsSection } from './TagsSection';
|
||||||
import { getNewSelectPartOptions, getNewGroupByPartOptions, makePartList } from './partListUtils';
|
import { getNewGroupByPartOptions, getNewSelectPartOptions, makePartList } from './partListUtils';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
query: InfluxQuery;
|
query: InfluxQuery;
|
||||||
@ -52,8 +52,12 @@ function getTemplateVariableOptions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper function to make it easy to call this from the widget-render-code
|
// helper function to make it easy to call this from the widget-render-code
|
||||||
function withTemplateVariableOptions(optionsPromise: Promise<string[]>): Promise<string[]> {
|
function withTemplateVariableOptions(optionsPromise: Promise<string[]>, filter?: string): Promise<string[]> {
|
||||||
return optionsPromise.then((options) => [...getTemplateVariableOptions(), ...options]);
|
let templateVariableOptions = getTemplateVariableOptions();
|
||||||
|
if (filter) {
|
||||||
|
templateVariableOptions = templateVariableOptions.filter((tvo) => tvo.indexOf(filter) > -1);
|
||||||
|
}
|
||||||
|
return optionsPromise.then((options) => [...templateVariableOptions, ...options]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is possible to add fields into the `InfluxQueryTag` structures, and they do work,
|
// it is possible to add fields into the `InfluxQueryTag` structures, and they do work,
|
||||||
@ -142,7 +146,8 @@ export const Editor = (props: Props): JSX.Element => {
|
|||||||
filterTags(query.tags ?? [], keys),
|
filterTags(query.tags ?? [], keys),
|
||||||
datasource
|
datasource
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
filter
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onChange={handleFromSectionChange}
|
onChange={handleFromSectionChange}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { cx, css } from '@emotion/css';
|
import { css, cx } from '@emotion/css';
|
||||||
import debouncePromise from 'debounce-promise';
|
import debouncePromise from 'debounce-promise';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useAsyncFn } from 'react-use';
|
import { useAsyncFn } from 'react-use';
|
||||||
|
|
||||||
import { SelectableValue } from '@grafana/data';
|
import { SelectableValue } from '@grafana/data';
|
||||||
import { InlineLabel, Select, AsyncSelect, Input } from '@grafana/ui';
|
import { AsyncSelect, InlineLabel, Input, Select } from '@grafana/ui';
|
||||||
|
|
||||||
import { useShadowedState } from '../useShadowedState';
|
import { useShadowedState } from '../useShadowedState';
|
||||||
|
|
||||||
@ -86,6 +86,7 @@ const SelReload = ({ loadOptions, allowCustomValue, onChange, onClose }: SelRelo
|
|||||||
allowCustomValue={allowCustomValue}
|
allowCustomValue={allowCustomValue}
|
||||||
loadOptions={debouncedLoadOptions}
|
loadOptions={debouncedLoadOptions}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
createOptionPosition="first"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -116,6 +117,7 @@ const SelSingleLoad = ({ loadOptions, allowCustomValue, onChange, onClose }: Sel
|
|||||||
allowCustomValue={allowCustomValue}
|
allowCustomValue={allowCustomValue}
|
||||||
options={loadState.value ?? []}
|
options={loadState.value ?? []}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
createOptionPosition="first"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user