Skip to content

Commit

Permalink
EZP-31299: Added 'search in specific language' feature (#1223)
Browse files Browse the repository at this point in the history
  • Loading branch information
michal-myszka authored Feb 28, 2020
1 parent f8f926d commit b6cf000
Show file tree
Hide file tree
Showing 28 changed files with 764 additions and 190 deletions.
59 changes: 49 additions & 10 deletions src/bundle/Controller/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
*/
namespace EzSystems\EzPlatformAdminUiBundle\Controller;

use eZ\Publish\API\Repository\Values\Content\Language;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
use eZ\Publish\API\Repository\Values\User\User;
use eZ\Publish\Core\Pagination\Pagerfanta\ContentSearchAdapter;
use eZ\Publish\API\Repository\SearchService;
use eZ\Publish\API\Repository\SectionService;
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\Core\Pagination\Pagerfanta\ContentSearchHitAdapter;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentEditData;
use EzSystems\EzPlatformAdminUi\Form\Data\Search\SearchData;
use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory;
use EzSystems\EzPlatformAdminUi\Form\SubmitHandler;
use EzSystems\EzPlatformAdminUi\Tab\Dashboard\PagerContentToDataMapper;
use EzSystems\EzPlatformAdminUi\Search\PagerSearchContentToDataMapper;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -29,8 +30,8 @@ class SearchController extends Controller
/** @var \eZ\Publish\API\Repository\SearchService */
private $searchService;

/** @var \EzSystems\EzPlatformAdminUi\Tab\Dashboard\PagerContentToDataMapper */
private $pagerContentToDataMapper;
/** @var \EzSystems\EzPlatformAdminUi\Search\PagerSearchContentToDataMapper */
private $pagerSearchContentToDataMapper;

/** @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface */
private $urlGenerator;
Expand All @@ -55,7 +56,7 @@ class SearchController extends Controller

/**
* @param \eZ\Publish\API\Repository\SearchService $searchService
* @param \EzSystems\EzPlatformAdminUi\Tab\Dashboard\PagerContentToDataMapper $pagerContentToDataMapper
* @param \EzSystems\EzPlatformAdminUi\Search\PagerSearchContentToDataMapper $pagerSearchContentToDataMapper
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $urlGenerator
* @param \EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory $formFactory
* @param \EzSystems\EzPlatformAdminUi\Form\SubmitHandler $submitHandler
Expand All @@ -66,7 +67,7 @@ class SearchController extends Controller
*/
public function __construct(
SearchService $searchService,
PagerContentToDataMapper $pagerContentToDataMapper,
PagerSearchContentToDataMapper $pagerSearchContentToDataMapper,
UrlGeneratorInterface $urlGenerator,
FormFactory $formFactory,
SubmitHandler $submitHandler,
Expand All @@ -76,7 +77,7 @@ public function __construct(
array $userContentTypeIdentifier
) {
$this->searchService = $searchService;
$this->pagerContentToDataMapper = $pagerContentToDataMapper;
$this->pagerSearchContentToDataMapper = $pagerSearchContentToDataMapper;
$this->urlGenerator = $urlGenerator;
$this->formFactory = $formFactory;
$this->submitHandler = $submitHandler;
Expand Down Expand Up @@ -109,6 +110,7 @@ public function searchAction(Request $request): Response
$lastModified = $search['last_modified'] ?? [];
$created = $search['created'] ?? [];
$subtree = $search['subtree'] ?? null;
$searchLanguage = null;

if (!empty($search['section'])) {
$section = $this->sectionService->loadSection($search['section']);
Expand All @@ -120,7 +122,18 @@ public function searchAction(Request $request): Response
}

$form = $this->formFactory->createSearchForm(
new SearchData($limit, $page, $query, $section, $contentTypes, $lastModified, $created, $creator, $subtree),
new SearchData(
$limit,
$page,
$query,
$section,
$contentTypes,
$lastModified,
$created,
$creator,
$subtree,
$searchLanguage
),
'search',
[
'method' => Request::METHOD_GET,
Expand All @@ -141,6 +154,10 @@ public function searchAction(Request $request): Response
$created = $data->getCreated();
$creator = $data->getCreator();
$subtree = $data->getSubtree();
$searchLanguageCode = ($data->getSearchLanguage() instanceof Language)
? $data->getSearchLanguage()->languageCode
: null;

$query = new Query();
$criteria = [];

Expand Down Expand Up @@ -185,8 +202,10 @@ public function searchAction(Request $request): Response
$query->sortClauses[] = new SortClause\DateModified(Query::SORT_ASC);
}

$languageFilter = $this->getSearchLanguageFilter($searchLanguageCode, $queryString);

$pagerfanta = new Pagerfanta(
new ContentSearchAdapter($query, $this->searchService)
new ContentSearchHitAdapter($query, $this->searchService, $languageFilter)
);

$pagerfanta->setMaxPerPage($limit);
Expand All @@ -197,7 +216,7 @@ public function searchAction(Request $request): Response
);

return $this->render('@ezdesign/admin/search/search.html.twig', [
'results' => $this->pagerContentToDataMapper->map($pagerfanta),
'results' => $this->pagerSearchContentToDataMapper->map($pagerfanta),
'form' => $form->createView(),
'pager' => $pagerfanta,
'form_edit' => $editForm->createView(),
Expand All @@ -212,4 +231,24 @@ public function searchAction(Request $request): Response
'user_content_type_identifier' => $this->userContentTypeIdentifier,
]);
}

/**
* @param string|null $languageCode
* @param string|null $queryString
*
* @return array
*/
private function getSearchLanguageFilter(?string $languageCode, ?string $queryString): array
{
$filter = [
'languages' => !empty($languageCode) ? [$languageCode] : [],
'useAlwaysAvailable' => true,
];

if (!empty($queryString)) {
$filter['excludeTranslationsFromAlwaysAvailable'] = false;
}

return $filter;
}
}
1 change: 1 addition & 0 deletions src/bundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ imports:
- { resource: services/permissions.yml }
- { resource: services/forms.yml }
- { resource: services/query_types.yaml }
- { resource: services/search.yml }

services:
_defaults:
Expand Down
1 change: 1 addition & 0 deletions src/bundle/Resources/config/services/dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ services:
- { name: ezplatform.tab, group: dashboard-everyone }

EzSystems\EzPlatformAdminUi\Tab\Dashboard\PagerContentToDataMapper:
parent: EzSystems\EzPlatformAdminUi\Search\AbstractPagerContentToDataMapper
autowire: true
public: false

Expand Down
6 changes: 5 additions & 1 deletion src/bundle/Resources/config/services/forms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ services:

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\LanguageChoiceLoader:
arguments:
$siteAccessLanguages: '$languages$'
$configResolver: "@ezpublish.config.resolver"

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\ConfiguredLanguagesChoiceLoader:
arguments:
$configResolver: "@ezpublish.config.resolver"

EzSystems\EzPlatformAdminUi\Form\Type\ChoiceList\Loader\PermissionAwareContentTypeChoiceLoader:
arguments:
Expand Down
10 changes: 10 additions & 0 deletions src/bundle/Resources/config/services/search.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
EzSystems\EzPlatformAdminUi\Search\AbstractPagerContentToDataMapper:
abstract: true
autowire: true
public: false

EzSystems\EzPlatformAdminUi\Search\PagerSearchContentToDataMapper:
parent: EzSystems\EzPlatformAdminUi\Search\AbstractPagerContentToDataMapper
autowire: true
public: false
7 changes: 4 additions & 3 deletions src/bundle/Resources/encore/ez.js.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,10 @@ module.exports = (Encore) => {
.addEntry('ezplatform-admin-ui-search-js', [
path.resolve(__dirname, '../public/js/scripts/button.content.edit.js'),
path.resolve(__dirname, '../public/js/scripts/admin.search.filters.js'),
path.resolve(__dirname, '../public/js/scripts/admin.search.js'),
path.resolve(__dirname, '../public/js/scripts/udw/select.location.js'),
path.resolve(__dirname, '../public/js/scripts/admin.content.tree.js'),
path.resolve(__dirname, '../public/js/scripts/button.translation.edit.js'),
])
.addEntry('ezplatform-admin-ui-section-list-js', [
path.resolve(__dirname, '../public/js/scripts/admin.section.list.js'),
Expand Down Expand Up @@ -212,9 +214,7 @@ module.exports = (Encore) => {
path.resolve(__dirname, '../public/js/scripts/admin.location.bookmark.js'),
path.resolve(__dirname, '../public/js/scripts/admin.main.translation.update.js'),
])
.addEntry('ezplatform-admin-ui-modal-location-trash-js', [
path.resolve(__dirname, '../public/js/scripts/admin.trash.js'),
])
.addEntry('ezplatform-admin-ui-modal-location-trash-js', [path.resolve(__dirname, '../public/js/scripts/admin.trash.js')])
.addEntry('ezplatform-admin-ui-modal-location-trash-container-js', [
path.resolve(__dirname, '../public/js/scripts/button.state.checkbox.toggle.js'),
path.resolve(__dirname, '../public/js/scripts/admin.trash.container.js'),
Expand All @@ -227,6 +227,7 @@ module.exports = (Encore) => {
path.resolve(__dirname, '../public/js/scripts/cotf/create.js'),
path.resolve(__dirname, '../public/js/scripts/button.content.edit.js'),
path.resolve(__dirname, '../public/js/scripts/admin.version.edit.conflict.js'),
path.resolve(__dirname, '../public/js/scripts/button.translation.edit.js'),
])
.addEntry('ezplatform-admin-ui-link-manager-list-js', [path.resolve(__dirname, '../public/js/scripts/admin.linkmanager.list.js')])
.addEntry('ezplatform-admin-ui-link-manager-view-js', [path.resolve(__dirname, '../public/js/scripts/button.content.edit.js')])
Expand Down
12 changes: 12 additions & 0 deletions src/bundle/Resources/public/js/scripts/admin.search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(function(global, doc) {
const languageSelector = doc.querySelector('.ez-search-form__language-selector');
const submitForm = (event) => {
event.target.closest('form').submit();
};

if (!languageSelector) {
return;
}

languageSelector.addEventListener('change', submitForm, false);
})(window, document);
77 changes: 77 additions & 0 deletions src/bundle/Resources/public/js/scripts/button.translation.edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
(function(global, doc) {
class EditTranslation {
constructor(config) {
this.container = config.container;
this.toggler = config.container.querySelector('.ez-btn--translations-list-toggler');
this.translationsList = config.container.querySelector('.ez-translation-selector__list-wrapper');
this.listTriangle = config.container.querySelector('.ez-translation-selector__list-triangle');

this.hideTranslationsList = this.hideTranslationsList.bind(this);
this.showTranslationsList = this.showTranslationsList.bind(this);
this.setPosition = this.setPosition.bind(this);
}

setPosition() {
const togglerRect = this.toggler.getBoundingClientRect();
const translationsListRect = this.translationsList.getBoundingClientRect();
const topPosition = togglerRect.top + togglerRect.height / 2 - translationsListRect.height / 2;
const leftPosition = togglerRect.left - translationsListRect.width - 10;

if (topPosition + translationsListRect.height > window.innerHeight) {
this.translationsList.style.bottom = 0;
this.translationsList.style.top = 'auto';

const translationsListRect = this.translationsList.getBoundingClientRect();
const listTriangleTopPosition =
((togglerRect.top + togglerRect.height / 2 - translationsListRect.top) / translationsListRect.height) * 100;

this.listTriangle.style.top = listTriangleTopPosition < 90 ? `${listTriangleTopPosition}%` : '90%';
} else {
this.translationsList.style.top = `${topPosition}px`;
this.translationsList.style.bottom = 'auto';
this.listTriangle.style.top = '50%';
}

this.translationsList.style.left = `${leftPosition}px`;

this.translationsList.classList.remove('ez-translation-selector__list-wrapper--visually-hidden');
}

hideTranslationsList(event) {
const closestTranslationSelector = event.target.closest('.ez-translation-selector');
const clickedOnTranslationsList = closestTranslationSelector && closestTranslationSelector.isSameNode(this.container);
const clickedOnDraftConflictModal = event.target.closest('.ez-modal--version-draft-conflict');

if (clickedOnTranslationsList || clickedOnDraftConflictModal) {
return;
}

this.translationsList.classList.add('ez-translation-selector__list-wrapper--hidden');
this.translationsList.classList.add('ez-translation-selector__list-wrapper--visually-hidden');

global.removeEventListener('scroll', this.setPosition, false);
doc.removeEventListener('click', this.hideTranslationsList, false);
}

showTranslationsList() {
this.translationsList.classList.remove('ez-translation-selector__list-wrapper--hidden');

this.setPosition();

global.addEventListener('scroll', this.setPosition, false);
doc.addEventListener('click', this.hideTranslationsList, false);
}

init() {
this.toggler.addEventListener('click', this.showTranslationsList, false);
}
}

const translationSelectors = doc.querySelectorAll('.ez-translation-selector');

translationSelectors.forEach((translationSelector) => {
const editTranslation = new EditTranslation({ container: translationSelector });

editTranslation.init();
});
})(window, document);
64 changes: 64 additions & 0 deletions src/bundle/Resources/public/scss/_translation-selector.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.ez-translation-selector {
&__list-wrapper {
display: block;
position: fixed;
opacity: 1;
text-align: left;
background-color: $ez-color-secondary;
padding: calculateRem(9px);
border-radius: calculateRem(4px);

&--hidden {
display: none;
}

&--visually-hidden {
opacity: 0;
}
}

&__list-triangle {
position: absolute;
right: 0;
top: 50%;
transform: translate(100%, -50%);

&:after {
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: calculateRem(5px) 0 calculateRem(5px) calculateRem(5px);
border-color: transparent transparent transparent $ez-color-secondary;
position: absolute;
z-index: 1;
}
}

&__title {
color: $ez-white;
font-size: calculateRem(16px);
line-height: 2;
font-weight: bold;
}

&__list {
display: flex;
flex-direction: column;
background-color: $ez-ground-base;
padding: calculateRem(8px);
max-height: calculateRem(300px);
overflow: auto;

.ez-btn--content-edit {
background-color: $ez-white;
color: $ez-color-secondary;
padding: calculateRem(9px) calculateRem(24px);
text-align: left;

&:not(:last-child) {
margin-bottom: calculateRem(8px);
}
}
}
}
1 change: 1 addition & 0 deletions src/bundle/Resources/public/scss/ezplatform.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@import 'content-type-selector';
@import 'labels';
@import 'tag';
@import 'translation-selector';
@import 'core/custom.dropdown';
@import 'fieldType/edit/base-field';
@import 'fieldType/edit/base-preview';
Expand Down
Loading

0 comments on commit b6cf000

Please sign in to comment.