From d667c3a4539d5908dd01adc3487aa2e1bc5fbf0f Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Sat, 11 Dec 2021 17:38:34 +0000 Subject: [PATCH] [COMPONENTS][Search][UI] Add options to filter by note or actor type. Reorganize UI --- components/Search/Controller/Search.php | 63 ++++++++++++++++--- .../Search/templates/search/show.html.twig | 60 +++++++++++++++++- 2 files changed, 111 insertions(+), 12 deletions(-) diff --git a/components/Search/Controller/Search.php b/components/Search/Controller/Search.php index 515921223c..3eb97dc61b 100644 --- a/components/Search/Controller/Search.php +++ b/components/Search/Controller/Search.php @@ -32,8 +32,10 @@ use App\Util\Common; use App\Util\Exception\BugFoundException; use App\Util\Exception\RedirectException; use App\Util\Form\FormFields; +use App\Util\Formatting; use Component\Search as Comp; use Component\Search\Util\Parser; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; @@ -68,20 +70,36 @@ class Search extends FeedController } $search_builder_form = Form::create([ - /* note-langs */ FormFields::language($actor, context_actor: null, label: _m('Search for notes in these languages'), multiple: true, required: false, use_short_display: false, form_id: 'note-langs', use_no_selection: true), - ['note-tags', TextType::class, ['required' => false, 'label' => _m('Include only notes with all the following tags')]], - /* note-actor-langs */ FormFields::language($actor, context_actor: null, label: _m('Search for notes by people who know these languages'), multiple: true, required: false, use_short_display: false, form_id: 'note-actor-langs', use_no_selection: true), - ['note-actor-tags', TextType::class, ['required' => false, 'label' => _m('Include only notes by people with all the following tags')]], - /* actor-langs */ FormFields::language($actor, context_actor: null, label: _m('Search for people that know these languages'), multiple: true, required: false, use_short_display: false, form_id: 'actor-langs', use_no_selection: true), - ['actor-tags', TextType::class, ['required' => false, 'label' => _m('Include only people with all the following tags')]], + ['include_actors', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include people/actors')]], + ['include_actors_groups', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include groups')]], + ['include_actors_lists', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include people lists')]], + ['include_actors_people', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include people')]], + ['include_actors_businesses', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include businesses')]], + ['include_actors_organizations', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include organizations')]], + ['include_actors_bots', CheckboxType::class, ['required' => false, 'data' => false, 'label' => _m('Include bots')]], + ['include_notes', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Include notes')]], + ['include_notes_text', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Include text notes')]], + ['include_notes_media', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Include media notes')]], + ['include_notes_polls', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Include polls')]], + ['include_notes_bookmarks', CheckboxType::class, ['required' => false, 'data' => true, 'label' => _m('Include bookmarks')]], + /* note_langs */ FormFields::language($actor, context_actor: null, label: _m('Search for notes in these languages'), multiple: true, required: false, use_short_display: false, form_id: 'note_langs', use_no_selection: true), + ['note_tags', TextType::class, ['required' => false, 'label' => _m('Include only notes with all the following tags')]], + /* note_actor_langs */ FormFields::language($actor, context_actor: null, label: _m('Search for notes by people who know these languages'), multiple: true, required: false, use_short_display: false, form_id: 'note_actor_langs', use_no_selection: true), + ['note_actor_tags', TextType::class, ['required' => false, 'label' => _m('Include only notes by people with all the following tags')]], + /* actor_langs */ FormFields::language($actor, context_actor: null, label: _m('Search for people that know these languages'), multiple: true, required: false, use_short_display: false, form_id: 'actor_langs', use_no_selection: true), + ['actor_tags', TextType::class, ['required' => false, 'label' => _m('Include only people with all the following tags')]], [$form_name = 'search_builder', SubmitType::class, ['label' => _m('Search')]], ]); if ('POST' === $request->getMethod() && $request->request->has($form_name)) { $search_builder_form->handleRequest($request); if ($search_builder_form->isSubmitted() && $search_builder_form->isValid()) { - $data = $search_builder_form->getData(); - $query = []; + $data = $search_builder_form->getData(); + $query = []; + $include_notes_query = []; + $include_actors_query = []; + $exception = new BugFoundException('Search builder form seems to have new fields the code did not expect'); + foreach ($data as $key => $value) { if (!\is_null($value) && !empty($value)) { if (str_contains($key, 'tags')) { @@ -91,11 +109,38 @@ class Search extends FeedController $langs = implode(',', $value); $query[] = "{$key}:{$langs}"; } + } elseif (str_contains($key, 'include')) { + if (str_contains($key, 'notes')) { + if ($key === 'include_notes') { + if (!$data[$key]) { + $include_notes_query = null; + } + } elseif ($data[$key] && !\is_null($include_notes_query)) { + $include_notes_query[] = Formatting::removePrefix($key, 'include_notes_'); + } + } elseif (str_contains($key, 'actors')) { + if ($key === 'include_actors') { + if (!$data[$key]) { + $include_actors_query = null; + } + } elseif ($data[$key] && !\is_null($include_actors_query)) { + $include_actors_query[] = Formatting::removePrefix($key, 'include_actors_'); + } + } else { + throw $exception; + } } else { - throw new BugFoundException('Search builder form seems to have new fields the code did not expect'); + throw $exception; } } } + + if (!\is_null($include_notes_query) && !empty($include_notes_query)) { + $query[] = 'note-types:' . implode(',', $include_notes_query); + } + if (!\is_null($include_actors_query) && !empty($include_actors_query)) { + $query[] = 'actor-types:' . implode(',', $include_actors_query); + } $query = implode(' ', $query); throw new RedirectException('search', ['q' => $query]); } diff --git a/components/Search/templates/search/show.html.twig b/components/Search/templates/search/show.html.twig index db467d699f..eae17d7722 100644 --- a/components/Search/templates/search/show.html.twig +++ b/components/Search/templates/search/show.html.twig @@ -16,16 +16,70 @@ {% endif %}
- {{ form(search_form) }} + {{ form_start(search_form) }} +
+ {{ form_row(search_form.search_query) }} + {{ form_row(search_form.submit_search) }} +
+
+ +

+ {% trans %}Save this search as a feed{% endtrans %} + {{ icon('arrow-down', 'icon icon-details-open') | raw }} +

+
+ {{ form_row(search_form.title) }} + {{ form_row(search_form.subscribe_to_search) }} +
+ {{ form_end(search_form)}}
-
+

{% trans %}Build a search query{% endtrans %} {{ icon('arrow-down', 'icon icon-details-open') | raw }}

- {{ form(search_builder_form) }} + + {{ form_start(search_builder_form) }} + + {# actor options, display if first checked, with checkbox trick #} +
+ +

+ {% trans %}People search options{% endtrans %} + {{ icon('arrow-down', 'icon icon-details-open') | raw }} +

+
+ {{ form_row(search_builder_form.include_actors) }} + {{ form_row(search_builder_form.include_actors_people) }} + {{ form_row(search_builder_form.include_actors_groups) }} + {{ form_row(search_builder_form.include_actors_lists) }} + {{ form_row(search_builder_form.include_actors_businesses) }} + {{ form_row(search_builder_form.include_actors_organizations) }} + {{ form_row(search_builder_form.include_actors_bots) }} + {{ form_row(search_builder_form.actor_langs) }} + {{ form_row(search_builder_form.actor_tags) }} +
+ +
+ +

+ {% trans %}Note search options{% endtrans %} + {{ icon('arrow-down', 'icon icon-details-open') | raw }} +

+
+ {{ form_row(search_builder_form.include_notes) }} + {{ form_row(search_builder_form.include_notes_text) }} + {{ form_row(search_builder_form.include_notes_media) }} + {{ form_row(search_builder_form.include_notes_polls) }} + {{ form_row(search_builder_form.include_notes_bookmarks) }} + {{ form_row(search_builder_form.note_langs) }} + {{ form_row(search_builder_form.note_tags) }} + {{ form_row(search_builder_form.note_actor_langs) }} + {{ form_row(search_builder_form.note_actor_tags) }} +
+ {{ form_end(search_builder_form) }}