From 1671a3d4bed33013da1f667357cd2740e3b8ca96 Mon Sep 17 00:00:00 2001 From: Bartek Wajda Date: Wed, 27 Nov 2024 16:14:16 +0100 Subject: [PATCH] IBX-9169: Enabled searching by content's name in the Trash (#1388) For more details see https://issues.ibexa.co/browse/IBX-9169 and https://github.com/ibexa/admin-ui/pull/1388 Key changes: * Enabled searching by content's name in the Trash --- .../translations/ibexa_trash.en.xliff | 24 +++++- .../views/themes/admin/trash/list.html.twig | 83 ++++++++++++------- src/lib/Form/Data/Search/TrashSearchData.php | 19 ++++- src/lib/Form/Type/Search/TrashSearchType.php | 7 ++ src/lib/QueryType/TrashSearchQueryType.php | 4 + 5 files changed, 102 insertions(+), 35 deletions(-) diff --git a/src/bundle/Resources/translations/ibexa_trash.en.xliff b/src/bundle/Resources/translations/ibexa_trash.en.xliff index 263d24c3cf..7b066b87bb 100644 --- a/src/bundle/Resources/translations/ibexa_trash.en.xliff +++ b/src/bundle/Resources/translations/ibexa_trash.en.xliff @@ -6,9 +6,14 @@ The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. + + Creator + Creator + key: search.creator_input.label + - Search by creator - Search by creator + Type creator's name + Type creator's name key: search.creator_input.placeholder @@ -26,6 +31,16 @@ Restore in a new location key: trash.button.restore_new_location + + Sorry, there are no contents for your search. + Sorry, there are no contents for your search. + key: trash.content_not_found + + + Try again with new search criteria. + Try again with new search criteria. + key: trash.content_not_found.action_text + Content type Content type @@ -101,6 +116,11 @@ Any time key: trash.search.any_time + + Search by content name + Search by content name + key: trash.search.search_by_content_name + All All diff --git a/src/bundle/Resources/views/themes/admin/trash/list.html.twig b/src/bundle/Resources/views/themes/admin/trash/list.html.twig index 3714363208..b74857a087 100644 --- a/src/bundle/Resources/views/themes/admin/trash/list.html.twig +++ b/src/bundle/Resources/views/themes/admin/trash/list.html.twig @@ -24,10 +24,39 @@ {% endblock %} {% block content %} - {% set trash_search_params = app.request.get('trash_search') %} + {% set trash_search_params = app.request.get('trash_search') %} + {% set creator = form_search.vars.data ? form_search.vars.data.creator : '' %} + {% set creator_exists = creator is not empty %} + + {% set creatorSearch %} +
+ +
+
+ + +
+
    +
    +
    + {% endset %}
    {% set collapsible_items = [ + creatorSearch, form_row(form_search.content_type, { 'attr': {'class': 'ibexa-trash-search-form__item ibexa-trash-search-form__item--auto-send'} }), @@ -45,6 +74,7 @@ {% endif %} {% embed '@ibexadesign/ui/component/adaptive_filters/adaptive_filters.html.twig' with { + filters_id: 'ibexa_trash_list', form: form_search, is_inside_container: true, collapsible_items: collapsible_items, @@ -55,28 +85,11 @@ {% trans_default_domain 'ibexa_trash' %} {% block static_left_input %} -
    - {% set creator = form_search.vars.data ? form_search.vars.data.creator : '' %} - {% set creator_exists = creator is not empty ? true : false %} - -
    - - -
    -
      -
      - + {{ form_widget(form_search.content_name, { + has_search: true, + should_clear_button_send_form: true + }) + }} {{ form_widget(form_search.creator, {'attr': {'hidden': 'hidden'}}) }} {{ form_widget(form_search.sort, {'attr': {'hidden': 'hidden'}}) }} {{ form_widget(form_search.trashed_interval, {'attr': {'hidden': 'hidden'}}) }} @@ -239,18 +252,28 @@ ]) %} {% set has_search_params = trash_search_params|length > 0 - ? trash_search_params.creator is defined - or trash_search_params.content_type is defined - or trash_search_params.trashed is defined - or trash_search_params.section is defined + ? (trash_search_params.creator is defined and trash_search_params.creator is not empty) + or (trash_search_params.content_type is defined and trash_search_params.content_type is not empty) + or (trash_search_params.trashed is defined and trash_search_params.trashed is not empty) + or (trash_search_params.section is defined and trash_search_params.section is not empty) + or (trash_search_params.content_name is defined and trash_search_params.content_name is not empty) : false %} {% embed '@ibexadesign/ui/component/table/table.html.twig' with { - headline: custom_results_headline ?? results_headline(pager.getNbResults(), has_search_params), + headline: custom_results_headline ?? results_headline( + pager.getNbResults(), + has_search_params, + trash_search_params.content_name ?? null, + ), head_cols, body_rows, - empty_table_info_text: 'trash.empty'|trans|desc('Trash is empty. Content you send to Trash will show up here.'), + empty_table_info_text: has_search_params + ? 'trash.content_not_found'|trans|desc('Sorry, there are no contents for your search.') + : 'trash.empty'|trans|desc('Trash is empty. Content you send to Trash will show up here.'), + empty_table_action_text: has_search_params + ? 'trash.content_not_found.action_text'|trans|desc('Try again with new search criteria.') + : "", } %} {% set modal_create_data_target = 'create-wildcards-modal' %} {% set modal_delete_data_target = 'delete-wildcards-modal' %} @@ -328,7 +351,7 @@ } %} {% endif %} {% include '@ibexadesign/trash/modal/empty_trash_confirmation.html.twig' with {'form': form_trash_empty, 'trash_items_count': pager.nbResults} %} -
      + {% endblock %} {% block react_modules %} diff --git a/src/lib/Form/Data/Search/TrashSearchData.php b/src/lib/Form/Data/Search/TrashSearchData.php index 8e05e00d02..1c53925c7c 100644 --- a/src/lib/Form/Data/Search/TrashSearchData.php +++ b/src/lib/Form/Data/Search/TrashSearchData.php @@ -38,6 +38,8 @@ class TrashSearchData /** @var array|null */ private $sort; + private ?string $contentName; + public function __construct( ?int $limit = 10, ?int $page = 1, @@ -46,6 +48,7 @@ public function __construct( ?string $trashed = null, ?array $trashedInterval = [], ?User $creator = null, + ?string $contentName = null, ?array $sort = ['field' => 'trashed', 'direction' => 0] ) { $this->limit = $limit; @@ -55,6 +58,7 @@ public function __construct( $this->trashed = $trashed; $this->trashedInterval = $trashedInterval; $this->creator = $creator; + $this->contentName = $contentName; $this->sort = $sort; } @@ -128,6 +132,16 @@ public function setCreator(?User $creator): void $this->creator = $creator; } + public function getContentName(): ?string + { + return $this->contentName; + } + + public function setContentName(?string $contentName): void + { + $this->contentName = $contentName; + } + public function getSort(): ?array { return $this->sort; @@ -138,20 +152,19 @@ public function setSort(?array $sort): void $this->sort = $sort; } - /** - * @return bool - */ public function isFiltered(): bool { $contentType = $this->getContentType(); $section = $this->getSection(); $trashed = $this->getTrashedInterval(); $creator = $this->getCreator(); + $contentName = $this->getContentName(); return null !== $contentType || null !== $section || null !== $creator || + null !== $contentName || !empty($trashed); } } diff --git a/src/lib/Form/Type/Search/TrashSearchType.php b/src/lib/Form/Type/Search/TrashSearchType.php index 7000954bac..c584ad57a2 100644 --- a/src/lib/Form/Type/Search/TrashSearchType.php +++ b/src/lib/Form/Type/Search/TrashSearchType.php @@ -19,6 +19,7 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -57,6 +58,12 @@ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('page', HiddenType::class) + ->add('content_name', TextType::class, [ + 'required' => false, + 'attr' => [ + 'placeholder' => /** @Desc("Search by content name") */ 'trash.search.search_by_content_name', + ], + ]) ->add('content_type', ChoiceType::class, [ 'choice_loader' => $this->searchContentTypeChoiceLoader, 'choice_label' => 'name', diff --git a/src/lib/QueryType/TrashSearchQueryType.php b/src/lib/QueryType/TrashSearchQueryType.php index 2aa65a7640..a32dc021a2 100644 --- a/src/lib/QueryType/TrashSearchQueryType.php +++ b/src/lib/QueryType/TrashSearchQueryType.php @@ -91,6 +91,10 @@ protected function addCriteria(TrashSearchData $searchData, Query $query): void ); } + if ($searchData->getContentName() !== null) { + $criteria[] = new Criterion\ContentName($searchData->getContentName()); + } + if (!empty($criteria)) { $query->filter = new Criterion\LogicalAnd($criteria); }