mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Templating: fixes filtering options with more than 1000 entries (#24614)
* Templating: fixes filtering options with more then 1000 entries * Chore: reduces strict null errors by 2
This commit is contained in:
@@ -101,8 +101,8 @@ export const completeChangeVariableName = (identifier: VariableIdentifier, newNa
|
|||||||
) => {
|
) => {
|
||||||
const originalVariable = getVariable(identifier.id, getState());
|
const originalVariable = getVariable(identifier.id, getState());
|
||||||
const model = { ...cloneDeep(originalVariable), name: newName, id: newName };
|
const model = { ...cloneDeep(originalVariable), name: newName, id: newName };
|
||||||
const global = originalVariable.global;
|
const global = originalVariable.global!; // global is undefined because of old variable system
|
||||||
const index = originalVariable.index;
|
const index = originalVariable.index!; // index is undefined because of old variable system
|
||||||
const renamedIdentifier = toVariableIdentifier(model);
|
const renamedIdentifier = toVariableIdentifier(model);
|
||||||
|
|
||||||
dispatch(addVariable(toVariablePayload(renamedIdentifier, { global, index, model })));
|
dispatch(addVariable(toVariablePayload(renamedIdentifier, { global, index, model })));
|
||||||
|
@@ -3,6 +3,7 @@ import {
|
|||||||
hideOptions,
|
hideOptions,
|
||||||
initialState as optionsPickerInitialState,
|
initialState as optionsPickerInitialState,
|
||||||
moveOptionsHighlight,
|
moveOptionsHighlight,
|
||||||
|
OPTIONS_LIMIT,
|
||||||
optionsPickerReducer,
|
optionsPickerReducer,
|
||||||
OptionsPickerState,
|
OptionsPickerState,
|
||||||
showOptions,
|
showOptions,
|
||||||
@@ -607,6 +608,32 @@ describe('optionsPickerReducer', () => {
|
|||||||
highlightIndex: 0,
|
highlightIndex: 0,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('and option count is are greater then OPTIONS_LIMIT', () => {
|
||||||
|
it('then state should be correct', () => {
|
||||||
|
const searchQuery = 'option:1337';
|
||||||
|
|
||||||
|
const options = [];
|
||||||
|
for (let index = 0; index <= OPTIONS_LIMIT + 337; index++) {
|
||||||
|
options.push({ text: `option:${index}`, value: `option:${index}`, selected: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { initialState } = getVariableTestContext({
|
||||||
|
queryValue: searchQuery,
|
||||||
|
});
|
||||||
|
|
||||||
|
reducerTester<OptionsPickerState>()
|
||||||
|
.givenReducer(optionsPickerReducer, cloneDeep(initialState))
|
||||||
|
.whenActionIsDispatched(updateOptionsAndFilter(options))
|
||||||
|
.thenStateShouldEqual({
|
||||||
|
...cloneDeep(initialState),
|
||||||
|
options: [{ text: 'option:1337', value: 'option:1337', selected: false }],
|
||||||
|
selectedValues: [],
|
||||||
|
queryValue: 'option:1337',
|
||||||
|
highlightIndex: 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when updateOptionsFromSearch is dispatched and variable has searchFilter', () => {
|
describe('when updateOptionsFromSearch is dispatched and variable has searchFilter', () => {
|
||||||
|
@@ -34,6 +34,8 @@ export const initialState: OptionsPickerState = {
|
|||||||
multi: false,
|
multi: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const OPTIONS_LIMIT = 1000;
|
||||||
|
|
||||||
const getTags = (model: VariableWithMultiSupport) => {
|
const getTags = (model: VariableWithMultiSupport) => {
|
||||||
if (isQuery(model) && Array.isArray(model.tags)) {
|
if (isQuery(model) && Array.isArray(model.tags)) {
|
||||||
return cloneDeep(model.tags);
|
return cloneDeep(model.tags);
|
||||||
@@ -50,7 +52,7 @@ const applyLimit = (options: VariableOption[]): VariableOption[] => {
|
|||||||
if (!Array.isArray(options)) {
|
if (!Array.isArray(options)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return options.slice(0, Math.min(options.length, 1000));
|
return options.slice(0, Math.min(options.length, OPTIONS_LIMIT));
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDefaultSelection = (state: OptionsPickerState): OptionsPickerState => {
|
const updateDefaultSelection = (state: OptionsPickerState): OptionsPickerState => {
|
||||||
@@ -176,13 +178,14 @@ const optionsPickerSlice = createSlice({
|
|||||||
updateOptionsAndFilter: (state, action: PayloadAction<VariableOption[]>): OptionsPickerState => {
|
updateOptionsAndFilter: (state, action: PayloadAction<VariableOption[]>): OptionsPickerState => {
|
||||||
const searchQuery = (state.queryValue ?? '').toLowerCase();
|
const searchQuery = (state.queryValue ?? '').toLowerCase();
|
||||||
|
|
||||||
state.options = applyLimit(action.payload);
|
const filteredOptions = action.payload.filter(option => {
|
||||||
state.highlightIndex = 0;
|
|
||||||
state.options = state.options.filter(option => {
|
|
||||||
const text = Array.isArray(option.text) ? option.text.toString() : option.text;
|
const text = Array.isArray(option.text) ? option.text.toString() : option.text;
|
||||||
return text.toLowerCase().indexOf(searchQuery) !== -1;
|
return text.toLowerCase().indexOf(searchQuery) !== -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
state.options = applyLimit(filteredOptions);
|
||||||
|
state.highlightIndex = 0;
|
||||||
|
|
||||||
return applyStateChanges(state, updateSelectedValues);
|
return applyStateChanges(state, updateSelectedValues);
|
||||||
},
|
},
|
||||||
updateOptionsFromSearch: (state, action: PayloadAction<VariableOption[]>): OptionsPickerState => {
|
updateOptionsFromSearch: (state, action: PayloadAction<VariableOption[]>): OptionsPickerState => {
|
||||||
|
@@ -12,7 +12,7 @@ export const getVariable = <T extends VariableModel = VariableModel>(
|
|||||||
if (throwWhenMissing) {
|
if (throwWhenMissing) {
|
||||||
throw new Error(`Couldn't find variable with id:${id}`);
|
throw new Error(`Couldn't find variable with id:${id}`);
|
||||||
}
|
}
|
||||||
return undefined;
|
return (undefined as unknown) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.templating.variables[id] as T;
|
return state.templating.variables[id] as T;
|
||||||
|
@@ -19,7 +19,7 @@ function buildMetricTree(parent: string, depth: number): TreeNode[] {
|
|||||||
const chars = ['A', 'B', 'C'];
|
const chars = ['A', 'B', 'C'];
|
||||||
const children: TreeNode[] = [];
|
const children: TreeNode[] = [];
|
||||||
|
|
||||||
if (depth > 3) {
|
if (depth > 5) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user