Skip to content

Commit 2f7cf1c

Browse files
imp: Change quick search so it searches for tickets with any label
All the filters of the quick search form are acting as "OR" (selecting several statuses or priorities lists tickets that have status1 OR status2 / priority1 OR priority2). However, the labels behaved differently (label1 AND label2). This different behaviour was quite disturbing for new users. Now, the behaviour of labels is coherent with the other fields.
1 parent 2c4dc28 commit 2f7cf1c

File tree

4 files changed

+60
-33
lines changed

4 files changed

+60
-33
lines changed

src/SearchEngine/Ticket/QuickSearchFilter.php

+29-20
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,12 @@ public function getLabels(): Collections\Collection
220220
return $this->labels;
221221
}
222222

223-
public function addLabel(Entity\Label $label): void
224-
{
225-
if (!$this->labels->contains($label)) {
226-
$this->labels->add($label);
227-
}
228-
}
229-
230-
public function removeLabel(Entity\Label $label): void
223+
/**
224+
* @param Collections\Collection<int, Entity\Label> $values
225+
*/
226+
public function setLabels(Collections\Collection $values): void
231227
{
232-
$this->labels->removeElement($label);
228+
$this->labels = $values;
233229
}
234230

235231
/**
@@ -328,17 +324,9 @@ public function toTextualQuery(): string
328324
$textualQueryParts[] = "team:{$values}";
329325
}
330326

331-
foreach ($this->labels as $label) {
332-
$value = $label->getName();
333-
334-
if (
335-
str_contains($value, ' ') &&
336-
(!str_starts_with($value, '"') || !str_ends_with($value, '"'))
337-
) {
338-
$value = '"' . $value . '"';
339-
}
340-
341-
$textualQueryParts[] = "label:{$value}";
327+
if (!$this->labels->isEmpty()) {
328+
$values = $this->processLabelValues($this->labels);
329+
$textualQueryParts[] = "label:{$values}";
342330
}
343331

344332
if ($this->priorities) {
@@ -386,4 +374,25 @@ private function processTeamValues(Collections\Collection $teams): string
386374

387375
return implode(',', $teamIds);
388376
}
377+
378+
/**
379+
* @param Collections\Collection<int, Entity\Label> $labels
380+
*/
381+
private function processLabelValues(Collections\Collection $labels): string
382+
{
383+
$labelNames = array_map(function (Entity\Label $label): string {
384+
$value = $label->getName();
385+
386+
if (
387+
str_contains($value, ' ') &&
388+
(!str_starts_with($value, '"') || !str_ends_with($value, '"'))
389+
) {
390+
$value = '"' . $value . '"';
391+
}
392+
393+
return $value;
394+
}, $labels->toArray());
395+
396+
return implode(',', $labelNames);
397+
}
389398
}

src/SearchEngine/Ticket/QuickSearchFilterBuilder.php

+26-8
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function getFilter(?SearchEngine\Query $query = null): ?QuickSearchFilter
5757
$qualifier = $condition->getQualifier();
5858
$value = $condition->getValue();
5959

60-
if ($qualifier !== 'label' && isset($qualifiersAlreadySet[$qualifier])) {
60+
if (isset($qualifiersAlreadySet[$qualifier])) {
6161
return null;
6262
}
6363

@@ -90,13 +90,8 @@ public function getFilter(?SearchEngine\Query $query = null): ?QuickSearchFilter
9090
$teams = $this->processTeams($values);
9191
$quickSearchFilter->setTeams($teams);
9292
} elseif ($qualifier === 'label') {
93-
foreach ($values as $value) {
94-
$labels = $this->labelRepository->findByName($value);
95-
96-
foreach ($labels as $label) {
97-
$quickSearchFilter->addLabel($label);
98-
}
99-
}
93+
$labels = $this->processLabels($values);
94+
$quickSearchFilter->setLabels($labels);
10095
} elseif ($qualifier === 'type' && count($values) === 1) {
10196
$quickSearchFilter->setType($values[0]);
10297
} elseif ($qualifier === 'no' && $values[0] === 'assignee') {
@@ -162,4 +157,27 @@ private function processTeams(array $values): Collections\ArrayCollection
162157

163158
return new Collections\ArrayCollection($teams);
164159
}
160+
161+
/**
162+
* @param string[] $values
163+
*
164+
* @return Collections\ArrayCollection<int, Entity\Label>
165+
*/
166+
private function processLabels(array $values): Collections\ArrayCollection
167+
{
168+
/** @var Collections\ArrayCollection<int, Entity\Label> */
169+
$labels = new Collections\ArrayCollection();
170+
171+
foreach ($values as $value) {
172+
$matchingLabels = $this->labelRepository->findByName($value);
173+
174+
foreach ($matchingLabels as $label) {
175+
if (!$labels->contains($label)) {
176+
$labels->add($label);
177+
}
178+
}
179+
}
180+
181+
return $labels;
182+
}
165183
}

tests/Controller/Tickets/QuickSearchesControllerTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public function testPostNewWithLabels(): void
108108
],
109109
]);
110110

111-
$expectedQuery = urlencode('label:bar label:foo');
111+
$expectedQuery = urlencode('label:bar,foo');
112112
$this->assertResponseRedirects("/tickets?q={$expectedQuery}", 302);
113113
}
114114

tests/SearchEngine/Ticket/QuickSearchFilterBuilderTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public function testGetFilterWithPriorityConditionReturnsFilter(): void
180180
$this->assertSame(['high'], $ticketQuickSearchFilter->getPriorities());
181181
}
182182

183-
public function testGetFilterWithLabelConditionsReturnsFilter(): void
183+
public function testGetFilterWithLabelConditionReturnsFilter(): void
184184
{
185185
$fooLabel = Factory\LabelFactory::createOne([
186186
'name' => 'foo',
@@ -191,7 +191,7 @@ public function testGetFilterWithLabelConditionsReturnsFilter(): void
191191
$bazLabel = Factory\LabelFactory::createOne([
192192
'name' => 'BAZ',
193193
]);
194-
$query = SearchEngine\Query::fromString('label:foo label:baz');
194+
$query = SearchEngine\Query::fromString('label:foo,baz');
195195

196196
$ticketQuickSearchFilter = $this->ticketQuickSearchFilterBuilder->getFilter($query);
197197

@@ -368,12 +368,12 @@ public function testToTextualQueryWithLabel(): void
368368
Factory\LabelFactory::createOne([
369369
'name' => 'Bar Baz',
370370
]);
371-
$query = SearchEngine\Query::fromString('label:foo label:"bar baz"');
371+
$query = SearchEngine\Query::fromString('label:foo,"bar baz"');
372372
$ticketQuickSearchFilter = $this->ticketQuickSearchFilterBuilder->getFilter($query);
373373

374374
$textualQuery = $ticketQuickSearchFilter->toTextualQuery();
375375

376-
$this->assertSame('label:foo label:"Bar Baz"', $textualQuery);
376+
$this->assertSame('label:foo,"Bar Baz"', $textualQuery);
377377
}
378378

379379
public function testSetText(): void

0 commit comments

Comments
 (0)