Merge branch '27248-filtered-search-does-not-allow-filtering-labels-with-multiple-words' into 'master'
Fix filtering label and milestone with multiple words Closes #27248 and #27334 See merge request !8830
This commit is contained in:
commit
d2a2ba9381
3 changed files with 168 additions and 2 deletions
|
@ -28,7 +28,12 @@
|
|||
if (lastToken !== searchToken) {
|
||||
const title = updatedItem.title.toLowerCase();
|
||||
let value = lastToken.value.toLowerCase();
|
||||
value = value.replace(/"(.*?)"/g, str => str.slice(1).slice(0, -1));
|
||||
|
||||
// Removes the first character if it is a quotation so that we can search
|
||||
// with multiple words
|
||||
if ((value[0] === '"' || value[0] === '\'') && title.indexOf(' ') !== -1) {
|
||||
value = value.slice(1);
|
||||
}
|
||||
|
||||
// Eg. filterSymbol = ~ for labels
|
||||
const matchWithoutSymbol = lastToken.symbol === filterSymbol && title.indexOf(value) !== -1;
|
||||
|
@ -83,8 +88,9 @@
|
|||
const selectionStart = input.selectionStart;
|
||||
let inputValue = input.value;
|
||||
// Replace all spaces inside quote marks with underscores
|
||||
// (will continue to match entire string until an end quote is found if any)
|
||||
// This helps with matching the beginning & end of a token:key
|
||||
inputValue = inputValue.replace(/("(.*?)"|:\s+)/g, str => str.replace(/\s/g, '_'));
|
||||
inputValue = inputValue.replace(/(('[^']*'{0,1})|("[^"]*"{0,1})|:\s+)/g, str => str.replace(/\s/g, '_'));
|
||||
|
||||
// Get the right position for the word selected
|
||||
// Regex matches first space
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fix filtering with multiple words
|
||||
merge_request: 8830
|
||||
author:
|
|
@ -64,6 +64,68 @@
|
|||
const updatedItem = gl.DropdownUtils.filterWithSymbol('@', input, item);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
describe('filters multiple word title', () => {
|
||||
const multipleWordItem = {
|
||||
title: 'Community Contributions',
|
||||
};
|
||||
|
||||
it('should filter with double quote', () => {
|
||||
input.value = 'label:"';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with double quote and symbol', () => {
|
||||
input.value = 'label:~"';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with double quote and multiple words', () => {
|
||||
input.value = 'label:"community con';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with double quote, symbol and multiple words', () => {
|
||||
input.value = 'label:~"community con';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with single quote', () => {
|
||||
input.value = 'label:\'';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with single quote and symbol', () => {
|
||||
input.value = 'label:~\'';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with single quote and multiple words', () => {
|
||||
input.value = 'label:\'community con';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter with single quote, symbol and multiple words', () => {
|
||||
input.value = 'label:~\'community con';
|
||||
|
||||
const updatedItem = gl.DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
|
||||
expect(updatedItem.droplab_hidden).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterHint', () => {
|
||||
|
@ -130,5 +192,99 @@
|
|||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getInputSelectionPosition', () => {
|
||||
describe('word with trailing spaces', () => {
|
||||
const value = 'label:none ';
|
||||
|
||||
it('should return selectionStart when cursor is at the trailing space', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 11,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(11);
|
||||
expect(right).toBe(11);
|
||||
});
|
||||
|
||||
it('should return input when cursor is at the start of input', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 0,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(10);
|
||||
});
|
||||
|
||||
it('should return input when cursor is at the middle of input', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 7,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(10);
|
||||
});
|
||||
|
||||
it('should return input when cursor is at the end of input', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 10,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple words', () => {
|
||||
const value = 'label:~"Community Contribution"';
|
||||
|
||||
it('should return input when cursor is after the first word', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 17,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(31);
|
||||
});
|
||||
|
||||
it('should return input when cursor is before the second word', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 18,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(31);
|
||||
});
|
||||
});
|
||||
|
||||
describe('incomplete multiple words', () => {
|
||||
const value = 'label:~"Community Contribution';
|
||||
|
||||
it('should return entire input when cursor is at the start of input', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 0,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(30);
|
||||
});
|
||||
|
||||
it('should return entire input when cursor is at the end of input', () => {
|
||||
const { left, right } = gl.DropdownUtils.getInputSelectionPosition({
|
||||
selectionStart: 30,
|
||||
value,
|
||||
});
|
||||
|
||||
expect(left).toBe(0);
|
||||
expect(right).toBe(30);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
|
Loading…
Reference in a new issue