From 6a68fbb495b6def1c175a947c6a0e0d3b12e7b61 Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Mon, 9 Jan 2023 11:37:25 +0100 Subject: [PATCH] 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 --- .../src/components/Select/SelectBase.tsx | 2 ++ .../grafana-ui/src/components/Select/types.ts | 3 +++ .../VisualInfluxQLEditor/Editor.tags.test.tsx | 8 +++++++ .../VisualInfluxQLEditor/Editor.tsx | 23 +++++++++++-------- .../components/VisualInfluxQLEditor/Seg.tsx | 8 ++++--- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/grafana-ui/src/components/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Select/SelectBase.tsx index eb4dfe47e87..595ca3b1566 100644 --- a/packages/grafana-ui/src/components/Select/SelectBase.tsx +++ b/packages/grafana-ui/src/components/Select/SelectBase.tsx @@ -97,6 +97,7 @@ export function SelectBase({ className, closeMenuOnSelect = true, components, + createOptionPosition = 'last', defaultOptions, defaultValue, disabled = false, @@ -256,6 +257,7 @@ export function SelectBase({ creatableProps.allowCreateWhileLoading = allowCreateWhileLoading; creatableProps.formatCreateLabel = formatCreateLabel ?? defaultFormatCreateLabel; creatableProps.onCreateOption = onCreateOption; + creatableProps.createOptionPosition = createOptionPosition; creatableProps.isValidNewOption = isValidNewOption; } diff --git a/packages/grafana-ui/src/components/Select/types.ts b/packages/grafana-ui/src/components/Select/types.ts index d5cd28098c2..2747ae597cb 100644 --- a/packages/grafana-ui/src/components/Select/types.ts +++ b/packages/grafana-ui/src/components/Select/types.ts @@ -27,6 +27,8 @@ export interface SelectCommonProps { closeMenuOnSelect?: boolean; /** Used for custom components. For more information, see `react-select` */ components?: any; + /** Sets the position of the createOption element in your options list. Defaults to 'last' */ + createOptionPosition?: 'first' | 'last'; defaultValue?: any; disabled?: boolean; filterOption?: (option: SelectableValue, searchQuery: string) => boolean; @@ -140,6 +142,7 @@ export type ControlComponent = React.ComponentType>; export interface SelectableOptGroup { label: string; options: Array>; + [key: string]: any; } diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx index eccbb4d4d3a..a2f4b6a043f 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tags.test.tsx @@ -33,6 +33,14 @@ jest.mock('../../influxQLMetadataQuery', () => { }; }); +jest.mock('@grafana/runtime', () => { + return { + getTemplateSrv: jest.fn().mockReturnValueOnce({ + getVariables: jest.fn().mockReturnValueOnce([]), + }), + }; +}); + beforeEach(() => { (mockedMeta.getTagKeysForMeasurementAndTags as jest.Mock).mockClear(); }); diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx index 4000c6d422f..7935f6819c0 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Editor.tsx @@ -14,13 +14,13 @@ import { getTagValues, } from '../../influxQLMetadataQuery'; import { - normalizeQuery, - addNewSelectPart, - removeSelectPart, addNewGroupByPart, - removeGroupByPart, - changeSelectPart, + addNewSelectPart, changeGroupByPart, + changeSelectPart, + normalizeQuery, + removeGroupByPart, + removeSelectPart, } from '../../queryUtils'; import { InfluxQuery, InfluxQueryTag } from '../../types'; import { DEFAULT_RESULT_FORMAT } from '../constants'; @@ -32,7 +32,7 @@ import { InputSection } from './InputSection'; import { OrderByTimeSection } from './OrderByTimeSection'; import { PartListSection } from './PartListSection'; import { TagsSection } from './TagsSection'; -import { getNewSelectPartOptions, getNewGroupByPartOptions, makePartList } from './partListUtils'; +import { getNewGroupByPartOptions, getNewSelectPartOptions, makePartList } from './partListUtils'; type Props = { query: InfluxQuery; @@ -52,8 +52,12 @@ function getTemplateVariableOptions() { } // helper function to make it easy to call this from the widget-render-code -function withTemplateVariableOptions(optionsPromise: Promise): Promise { - return optionsPromise.then((options) => [...getTemplateVariableOptions(), ...options]); +function withTemplateVariableOptions(optionsPromise: Promise, filter?: string): Promise { + 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, @@ -142,7 +146,8 @@ export const Editor = (props: Props): JSX.Element => { filterTags(query.tags ?? [], keys), datasource ) - ) + ), + filter ) } onChange={handleFromSectionChange} diff --git a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx index c1ba0c6357b..a30d2a7f4c5 100644 --- a/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx +++ b/public/app/plugins/datasource/influxdb/components/VisualInfluxQLEditor/Seg.tsx @@ -1,10 +1,10 @@ -import { cx, css } from '@emotion/css'; +import { css, cx } from '@emotion/css'; import debouncePromise from 'debounce-promise'; -import React, { useState, useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { useAsyncFn } from 'react-use'; 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'; @@ -86,6 +86,7 @@ const SelReload = ({ loadOptions, allowCustomValue, onChange, onClose }: SelRelo allowCustomValue={allowCustomValue} loadOptions={debouncedLoadOptions} onChange={onChange} + createOptionPosition="first" /> ); @@ -116,6 +117,7 @@ const SelSingleLoad = ({ loadOptions, allowCustomValue, onChange, onClose }: Sel allowCustomValue={allowCustomValue} options={loadState.value ?? []} onChange={onChange} + createOptionPosition="first" /> );