OptionsPicker: Allow storing raw input even when matches exist (#84790)

This commit is contained in:
Leon Sorokin 2024-03-28 18:18:02 -05:00 committed by GitHub
parent 726a666059
commit db6b51cb88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 4 deletions

View File

@ -569,8 +569,11 @@ describe('optionsPickerReducer', () => {
.whenActionIsDispatched(updateOptionsAndFilter(options))
.thenStateShouldEqual({
...initialState,
options: [{ text: 'All', value: '$__all', selected: true }],
selectedValues: [{ text: 'All', value: '$__all', selected: true }],
options: [
{ text: '> A', value: 'A', selected: false },
{ text: 'All', value: '$__all', selected: false },
],
selectedValues: [],
queryValue: 'A',
highlightIndex: 0,
});
@ -815,6 +818,45 @@ describe('optionsPickerReducer', () => {
highlightIndex: 0,
});
});
it('should offer as-typed option even when matches exist', () => {
const searchQuery = 'a.*';
const options: VariableOption[] = 'A AA AB C'.split(' ').map((v) => ({
selected: false,
text: v,
value: v,
}));
const expect: VariableOption[] = [
{
selected: false,
text: '> ' + searchQuery,
value: searchQuery,
},
].concat(
'A AA AB'.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', () => {

View File

@ -267,12 +267,30 @@ const optionsPickerSlice = createSlice({
}
// always sort $__all to the top, even if exact match exists?
opts.sort((a, b) => (a.value === '$__all' ? -1 : 0) - (b.value === '$__all' ? -1 : 0));
opts.sort((a, b) => (a.value === ALL_VARIABLE_VALUE ? -1 : 0) - (b.value === ALL_VARIABLE_VALUE ? -1 : 0));
}
}
state.highlightIndex = 0;
if (needle !== '') {
// top ranked match index
let firstMatchIdx = opts.findIndex((o) => o.value !== ALL_VARIABLE_VALUE);
// if there's no match or no exact match, prepend as-typed option
if (firstMatchIdx === -1 || opts[firstMatchIdx].value !== needle) {
opts.unshift({
selected: false,
text: '> ' + needle,
value: needle,
});
// if no match at all, select as-typed, else select best match
state.highlightIndex = firstMatchIdx === -1 ? 0 : firstMatchIdx + 1;
}
}
state.options = opts;
state.highlightIndex = 0;
return applyStateChanges(state, updateDefaultSelection, updateOptions);
},