Skip to content

Commit

Permalink
imp: Allow to filter by teams with the quick search form
Browse files Browse the repository at this point in the history
  • Loading branch information
marien-probesys committed Jan 10, 2025
1 parent 411185e commit 44e2ddc
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/Form/Ticket/QuickSearchForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,20 @@ function (?string $value): string {
'block_prefix' => 'multiselect',
]);

$form->add('teams', AppType\TeamType::class, [
'multiple' => true,
'required' => false,
'label' => new TranslatableMessage('tickets.team'),
'organization' => $organization,
'label_attr' => [
'class' => 'text--bold',
],
'attr' => [
'data-placeholder' => $this->translator->trans('forms.multiselect.select_team'),
],
'block_prefix' => 'multiselect',
]);

$form->add('assignees', AppType\ActorType::class, [
'multiple' => true,
'required' => false,
Expand Down
37 changes: 37 additions & 0 deletions src/SearchEngine/Ticket/QuickSearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class QuickSearchFilter
/** @var Collections\Collection<int, Entity\User> */
private Collections\Collection $requesters;

/** @var Collections\Collection<int, Entity\Team> */
private Collections\Collection $teams;

/** @var Collections\Collection<int, Entity\Label> */
private Collections\Collection $labels;

Expand All @@ -49,6 +52,7 @@ public function __construct()
$this->involves = new Collections\ArrayCollection();
$this->assignees = new Collections\ArrayCollection();
$this->requesters = new Collections\ArrayCollection();
$this->teams = new Collections\ArrayCollection();
$this->labels = new Collections\ArrayCollection();
}

Expand Down Expand Up @@ -192,6 +196,22 @@ public function setRequesters(Collections\Collection $values): void
$this->requesters = $values;
}

/**
* @return Collections\Collection<int, Entity\Team>
*/
public function getTeams(): Collections\Collection
{
return $this->teams;
}

/**
* @param Collections\Collection<int, Entity\Team> $values
*/
public function setTeams(Collections\Collection $values): void
{
$this->teams = $values;
}

/**
* @return Collections\Collection<int, Entity\Label>
*/
Expand Down Expand Up @@ -303,6 +323,11 @@ public function toTextualQuery(): string
$textualQueryParts[] = "requester:{$values}";
}

if (!$this->teams->isEmpty()) {
$values = $this->processTeamValues($this->teams);
$textualQueryParts[] = "team:{$values}";
}

foreach ($this->labels as $label) {
$value = $label->getName();

Expand Down Expand Up @@ -349,4 +374,16 @@ private function processActorValues(Collections\Collection $actors): string

return implode(',', $actorIds);
}

/**
* @param Collections\Collection<int, Entity\Team> $teams
*/
private function processTeamValues(Collections\Collection $teams): string
{
$teamIds = array_map(function (Entity\Team $team): string {
return "#{$team->getId()}";
}, $teams->toArray());

return implode(',', $teamIds);
}
}
27 changes: 27 additions & 0 deletions src/SearchEngine/Ticket/QuickSearchFilterBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class QuickSearchFilterBuilder
{
public function __construct(
private Repository\LabelRepository $labelRepository,
private Repository\TeamRepository $teamRepository,
private Repository\UserRepository $userRepository,
private Security $security,
) {
Expand Down Expand Up @@ -85,6 +86,9 @@ public function getFilter(?SearchEngine\Query $query = null): ?QuickSearchFilter
} elseif ($qualifier === 'requester') {
$users = $this->processUsers($values);
$quickSearchFilter->setRequesters($users);
} elseif ($qualifier === 'team') {
$teams = $this->processTeams($values);
$quickSearchFilter->setTeams($teams);
} elseif ($qualifier === 'label') {
foreach ($values as $value) {
$labels = $this->labelRepository->findByName($value);
Expand Down Expand Up @@ -135,4 +139,27 @@ private function processUsers(array $values): Collections\ArrayCollection

return new Collections\ArrayCollection($users);
}

/**
* @param string[] $values
*
* @return Collections\ArrayCollection<int, Entity\Team>
*/
private function processTeams(array $values): Collections\ArrayCollection
{
$ids = [];

foreach ($values as $value) {
if (preg_match('/^#[\d]+$/', $value)) {
$value = substr($value, 1);
$ids[] = intval($value);
}
}

$teams = $this->teamRepository->findBy([
'id' => $ids,
]);

return new Collections\ArrayCollection($teams);
}
}
9 changes: 8 additions & 1 deletion templates/tickets/_search_form.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,25 @@

{% if quickSearchForm.involves is defined %}
{% set involvesIsSet = field_value(quickSearchForm.involves) is not empty %}
{% set teamsIsSet = field_value(quickSearchForm.teams) is not empty %}
{% set assigneesIsSet = field_value(quickSearchForm.assignees) is not empty %}
{% set unassignedOnlyIsSet = quickSearchForm.unassignedOnly.vars.checked %}
{% set requestersIsSet = field_value(quickSearchForm.requesters) is not empty %}

<details class="accordion" {{ involvesIsSet or assigneesIsSet or unassignedOnlyIsSet or requestersIsSet ? 'open' }}>
<details class="accordion" {{ involvesIsSet or teamsIsSet or assigneesIsSet or unassignedOnlyIsSet or requestersIsSet ? 'open' }}>
<summary class="accordion__title">
{{ 'tickets.filters.actors.title' | trans }}
</summary>

<div class="accordion__body flow flow--large">
{{ form_row(quickSearchForm.involves) }}

{% if quickSearchForm.teams.vars.choices is not empty %}
{{ form_row(quickSearchForm.teams) }}
{% else %}
{% do quickSearchForm.teams.setRendered %}
{% endif %}

<div class="flow flow--small" data-controller="checkboxes">
{{ form_row(quickSearchForm.assignees) }}

Expand Down
1 change: 1 addition & 0 deletions translations/messages+intl-icu.en_GB.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ forms.error: Error
forms.input_texts.remove: Remove
forms.max_chars: '(max. {number} characters)'
forms.multiselect.select_actor: 'Select an actor'
forms.multiselect.select_team: 'Select a team'
forms.multiselect.unselect: Unselect
forms.optional: (optional)
forms.optional_max_chars: '(optional, max. {number} characters)'
Expand Down
1 change: 1 addition & 0 deletions translations/messages+intl-icu.fr_FR.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ forms.error: Erreur
forms.input_texts.remove: Retirer
forms.max_chars: '(max. {number} caractères)'
forms.multiselect.select_actor: 'Sélectionner un acteur'
forms.multiselect.select_team: 'Sélectionner une équipe'
forms.multiselect.unselect: Désélectionner
forms.optional: (optionnel)
forms.optional_max_chars: '(optionnel, max. {number} caractères)'
Expand Down

0 comments on commit 44e2ddc

Please sign in to comment.