[v11.2.x] Templating: Fix searching non-latin template variables (#92893)

Templating: Fix searching non-latin template variables (#92789)

(cherry picked from commit 43c960dc97)

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
grafana-delivery-bot[bot]
2024-09-04 01:41:06 +03:00
committed by GitHub
parent 97a74d9e17
commit f051013f4e
2 changed files with 46 additions and 0 deletions

View File

@@ -860,6 +860,47 @@ describe('optionsPickerReducer', () => {
});
});
describe('when searching non-latin chars', () => {
it('should skip fuzzy matching and fall back to substring', () => {
const searchQuery = '水';
const options: VariableOption[] = 'A水'.split(' ').map((v) => ({
selected: false,
text: v,
value: v,
}));
const expect: VariableOption[] = [
{
selected: false,
text: '> ' + searchQuery,
value: searchQuery,
},
].concat(
'A水'.split(' ').map((v) => ({
selected: false,
text: v,
value: v,
}))
);
const { initialState } = getVariableTestContext({
queryValue: searchQuery,
});
reducerTester<OptionsPickerState>()
.givenReducer(optionsPickerReducer, cloneDeep(initialState))
.whenActionIsDispatched(updateOptionsAndFilter(options))
.thenStateShouldEqual({
...cloneDeep(initialState),
options: expect,
selectedValues: [],
queryValue: searchQuery,
highlightIndex: 1,
});
});
});
describe('when large data for updateOptionsFromSearch is dispatched and variable has searchFilter', () => {
it('then state should be correct', () => {
const searchQuery = '__searchFilter';

View File

@@ -8,6 +8,9 @@ import { applyStateChanges } from '../../../../core/utils/applyStateChanges';
import { ALL_VARIABLE_VALUE } from '../../constants';
import { isMulti, isQuery } from '../../guard';
// https://catonmat.net/my-favorite-regex :)
const REGEXP_NON_ASCII = /[^ -~]/gm;
export interface ToggleOption {
option?: VariableOption;
forceSelect: boolean;
@@ -251,6 +254,8 @@ const optionsPickerSlice = createSlice({
if (needle === '') {
opts = action.payload;
} else if (REGEXP_NON_ASCII.test(needle)) {
opts = action.payload.filter((o) => o.text.includes(needle));
} else {
// with current API, not seeing a way to cache this on state using action.payload's uniqueness
// since it's recreated and includes selected state on each item :(