mirror of https://github.com/grafana/grafana.git
				
				
				
			OptionsPicker: Allow storing raw input even when matches exist (#84790)
This commit is contained in:
		
							parent
							
								
									726a666059
								
							
						
					
					
						commit
						db6b51cb88
					
				| 
						 | 
				
			
			@ -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', () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue