bug #13724 Fix disappearing products in Admin Panel when translation for current locale is missing (jakubtobiasz)

This PR was merged into the 1.10 branch.

Discussion
----------

> Previous PR (#13721) was based on a master branch so I've created a new branch based on the `1.10` one, cherry-picked changes and applied suggestions from CR :).

| Q               | A
| --------------- | -----
| Branch?         | 1.10
| Bug fix?        | yes
| New feature?    | no
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | fixes #13296
| License         | MIT

**Description**
Hi 🙋🏻‍♂️!

Let's say our products has translations for `Polish (Poland)` and `English (United States)` locales. Currently if we switch to `Polish` or `English` or any other "non-supported" locale we can't see any product in Admin Panel.

This PR fixes it by displaying all the products and in case of missing name's translation displays `missing translation` info.
![CleanShot 2022-03-03 at 7 53 16](https://user-images.githubusercontent.com/80641364/156512398-7194c542-46ab-44cc-8d1b-f88653590af9.png)

Cases covered by tests:
- Products with missing translations sorted by name ascending should be displayed as first
- Products with missing translations sorted by name descending should be displayed as last

These two cases also covers implicitly:
- If product has missing translation display `missing translation` as a product name

In case any change needed just let me know ✌🏻.

Commits
-------

3e43756cbe Replace innerJoin with leftJoin in createListQueryBuilder
3c786da85f Replace product's name string with twig template
5107e63ed9 Add "missing translation" translation
01f594560b Add "missing-translation-paragraph" data test attribute
e8d956cc43 Add scenarios covering missing translations on the products list in AP
5d29b936a2 Remove implementation details from behat scenarios
This commit is contained in:
Łukasz Chruściel 2022-03-24 17:10:52 +01:00 committed by GitHub
commit 8f5ec0a31d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 4 deletions

View file

@ -13,6 +13,7 @@ Feature: Sorting listed products
And this product is named "Mops Miłości" in the "Polish (Poland)" locale
And the store also has a product "Xtreme Pug" with code "X_PUG"
And this product is named "Ekstremalny Mops" in the "Polish (Poland)" locale
And this product is named "Ekstremalny Mops" in the "Polish" locale
And I am logged in as an administrator
@ui @api
@ -63,3 +64,22 @@ Feature: Sorting listed products
And I sort the products descending by name
Then I should see 3 products in the list
And the first product on the list should have name "Szałowy Mops"
@ui
Scenario: Missing translations are sorted as first when sorting by name ascending
When I change my locale to "Polish"
And I browse products
And I sort the products ascending by name
Then I should see 3 products in the list
And the first product on the list shouldn't have a name
And the last product on the list should have name "Ekstremalny Mops"
@ui
Scenario: Missing translation are sorted as last when sorting by name descending
When I change my locale to "Polish"
And I browse products
And the products are already sorted ascending by name
And I sort the products descending by name
Then I should see 3 products in the list
And the first product on the list should have name "Ekstremalny Mops"
And the last product on the list shouldn't have a name

View file

@ -1164,6 +1164,22 @@ final class ManagingProductsContext implements Context
Assert::contains($price, $this->updateSimpleProductPage->getOriginalPriceForChannel($channel));
}
/**
* @Then the first product on the list shouldn't have a name
*/
public function theFirstProductOnTheListShouldNotHaveName(): void
{
Assert::true($this->indexPage->checkFirstProductHasDataAttribute('data-test-missing-translation-paragraph'));
}
/**
* @Then the last product on the list shouldn't have a name
*/
public function theLastProductOnTheListShouldNotHaveName(): void
{
Assert::true($this->indexPage->checkLastProductHasDataAttribute('data-test-missing-translation-paragraph'));
}
/**
* @param string $element
* @param string $value

View file

@ -68,11 +68,23 @@ class IndexPage extends CrudIndexPage implements IndexPageInterface
$field->clickLink('Details');
}
public function checkFirstProductHasDataAttribute(string $attributeName): bool
{
return $this->getElement('first_product')->find('css', sprintf('[%s]', $attributeName)) !== null;
}
public function checkLastProductHasDataAttribute(string $attributeName): bool
{
return $this->getElement('last_product')->find('css', sprintf('[%s]', $attributeName)) !== null;
}
protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
'channel_filter' => '#criteria_channel',
'taxon_filter' => '.sylius-tree__item a:contains("%taxon%")',
'first_product' => '.table > tbody > tr:first-child',
'last_product' => '.table > tbody > tr:last-child',
]);
}
}

View file

@ -26,4 +26,8 @@ interface IndexPageInterface extends CrudIndexPageInterface
public function chooseChannelFilter(string $channelName): void;
public function filter(): void;
public function checkFirstProductHasDataAttribute(string $attributeName): bool;
public function checkLastProductHasDataAttribute(string $attributeName): bool;
}

View file

@ -22,9 +22,11 @@ sylius_grid:
label: sylius.ui.code
sortable: ~
name:
type: string
type: twig
label: sylius.ui.name
sortable: translation.name
options:
template: "@SyliusAdmin/Product/Grid/Field/name.html.twig"
mainTaxon:
type: twig
label: sylius.ui.main_taxon

View file

@ -0,0 +1,7 @@
{% if data is not null %}
{{ data }}
{% else %}
<p class="text gray" {{ sylius_test_html_attribute('missing-translation-paragraph') }}>
<i class="exclamation circle icon"></i> <i>{{ 'sylius.ui.missing_translation'|trans }}</i>
</p>
{% endif %}

View file

@ -13,9 +13,8 @@ declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Doctrine\ORM;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\QueryBuilder;
use Sylius\Bundle\ProductBundle\Doctrine\ORM\ProductRepository as BaseProductRepository;
use Sylius\Component\Core\Model\ChannelInterface;
@ -39,7 +38,7 @@ class ProductRepository extends BaseProductRepository implements ProductReposito
{
$queryBuilder = $this->createQueryBuilder('o')
->addSelect('translation')
->innerJoin('o.translations', 'translation', 'WITH', 'translation.locale = :locale')
->leftJoin('o.translations', 'translation', 'WITH', 'translation.locale = :locale')
->setParameter('locale', $locale)
;

View file

@ -493,6 +493,7 @@ sylius:
meta_keywords: 'Meta keywords'
metadata_index: 'Metadata'
method: 'Method'
missing_translation: 'missing translation'
modified: 'Modified'
money: 'Money'
most_expensive_first: 'Most expensive first'