mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
[Admin] Add global alert for form errors (#16634)
| Q | A |-----------------|----- | Branch? | 2.0 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Related tickets | n/a | License | MIT 
This commit is contained in:
commit
7d9c78a1cf
15 changed files with 84 additions and 103 deletions
|
|
@ -12,7 +12,7 @@ Feature: Customer group validation
|
|||
When I want to create a new customer group
|
||||
And I try to add it
|
||||
Then I should be notified that name is required
|
||||
# And I should be informed that this form contains errors #TODO: Uncomment when flash messages are brought back
|
||||
And I should be informed that this form contains errors
|
||||
|
||||
@api @ui
|
||||
Scenario: Trying to remove name from an existing customer group
|
||||
|
|
@ -21,7 +21,7 @@ Feature: Customer group validation
|
|||
And I remove its name
|
||||
And I try to save my changes
|
||||
Then I should be notified that name is required
|
||||
# And I should be informed that this form contains errors #TODO: Uncomment when flash messages are brought back
|
||||
And I should be informed that this form contains errors
|
||||
And this customer group should still be named "Retail"
|
||||
|
||||
@api @ui
|
||||
|
|
|
|||
|
|
@ -14,24 +14,20 @@ declare(strict_types=1);
|
|||
namespace Sylius\Behat\Context\Ui\Admin;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface;
|
||||
use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait;
|
||||
use Sylius\Behat\Element\Admin\CustomerGroup\FormElementInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\IndexPageInterface;
|
||||
use Sylius\Behat\Page\Admin\CustomerGroup\CreatePageInterface;
|
||||
use Sylius\Behat\Page\Admin\CustomerGroup\UpdatePageInterface;
|
||||
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
|
||||
use Sylius\Component\Customer\Model\CustomerGroupInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final readonly class ManagingCustomerGroupsContext implements Context
|
||||
{
|
||||
use ValidationTrait;
|
||||
|
||||
public function __construct(
|
||||
private CreatePageInterface $createPage,
|
||||
private IndexPageInterface $indexPage,
|
||||
private CurrentPageResolverInterface $currentPageResolver,
|
||||
private UpdatePageInterface $updatePage,
|
||||
private FormElementInterface $formElement,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +45,15 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
*/
|
||||
public function iSpecifyItsCodeAs(?string $code = null): void
|
||||
{
|
||||
$this->createPage->specifyCode($code ?? '');
|
||||
$this->formElement->fillElement($code ?? '', 'code');
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I specify a too long code
|
||||
*/
|
||||
public function iSpecifyATooLongCode(): void
|
||||
{
|
||||
$this->formElement->fillElement(str_repeat('a', 256), 'code');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +62,7 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
*/
|
||||
public function iSpecifyItsNameAs(?string $name = null): void
|
||||
{
|
||||
$this->createPage->nameIt($name ?? '');
|
||||
$this->formElement->fillElement($name ?? '', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,7 +202,7 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
public function iShouldBeNotifiedThatNameIsRequired(): void
|
||||
{
|
||||
Assert::same(
|
||||
$this->updatePage->getValidationMessage('name'),
|
||||
$this->formElement->getValidationMessage('name'),
|
||||
'Please enter a customer group name.',
|
||||
);
|
||||
}
|
||||
|
|
@ -208,7 +212,18 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
*/
|
||||
public function iShouldBeNotifiedThatCustomerGroupWithThisCodeAlreadyExists(): void
|
||||
{
|
||||
Assert::same($this->createPage->getValidationMessage('code'), 'Customer group code has to be unique.');
|
||||
Assert::same($this->formElement->getValidationMessage('code'), 'Customer group code has to be unique.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be notified that code is too long
|
||||
*/
|
||||
public function iShouldBeNotifiedThatCodeIsTooLong(): void
|
||||
{
|
||||
Assert::contains(
|
||||
$this->formElement->getValidationMessage('code'),
|
||||
'must not be longer than 255 characters.',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -216,10 +231,7 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
*/
|
||||
public function iShouldBeInformedThatThisFormContainsErrors(): void
|
||||
{
|
||||
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
|
||||
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
|
||||
|
||||
Assert::contains($currentPage->getMessageInvalidForm(), 'This form contains errors');
|
||||
Assert::true($this->formElement->hasFormErrorAlert());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -227,7 +239,7 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
*/
|
||||
public function iShouldNotBeAbleToEditItsCode(): void
|
||||
{
|
||||
Assert::true($this->updatePage->isCodeDisabled());
|
||||
Assert::true($this->formElement->isCodeDisabled());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -253,9 +265,4 @@ final readonly class ManagingCustomerGroupsContext implements Context
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function resolveCurrentPage(): SymfonyPageInterface
|
||||
{
|
||||
return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,14 +44,19 @@ class FormElement extends Element implements FormElementInterface
|
|||
|
||||
public function getValidationErrors(): string
|
||||
{
|
||||
$validationMessage = $this->getDocument()->find('css', '.sylius-validation-error, .alert.alert-danger');
|
||||
$validationMessage = $this->getDocument()->find('css', 'form .alert.alert-danger');
|
||||
if (null === $validationMessage) {
|
||||
throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error, .alert.alert-danger');
|
||||
throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', 'form .alert.alert-danger');
|
||||
}
|
||||
|
||||
return $validationMessage->getText();
|
||||
}
|
||||
|
||||
public function hasFormErrorAlert(): bool
|
||||
{
|
||||
return $this->hasElement('form_error_alert');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
|
|
@ -59,6 +64,7 @@ class FormElement extends Element implements FormElementInterface
|
|||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'form' => 'form',
|
||||
'form_error_alert' => '[data-test-form-error-alert]',
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,4 +31,6 @@ interface FormElementInterface
|
|||
* @throws ElementNotFoundException
|
||||
*/
|
||||
public function getValidationErrors(): string;
|
||||
|
||||
public function hasFormErrorAlert(): bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,31 +11,26 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\CustomerGroup;
|
||||
namespace Sylius\Behat\Element\Admin\CustomerGroup;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
|
||||
use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement;
|
||||
|
||||
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
||||
final class FormElement extends BaseFormElement implements FormElementInterface
|
||||
{
|
||||
use ChecksCodeImmutability;
|
||||
|
||||
public function nameIt(string $name): void
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
$this->getElement('name')->setValue($name);
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '[data-test-code]',
|
||||
'name' => '[data-test-name]',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getCodeElement(): NodeElement
|
||||
{
|
||||
return $this->getElement('code');
|
||||
}
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '#sylius_admin_customer_group_code',
|
||||
'name' => '#sylius_admin_customer_group_name',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,13 +11,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\CustomerGroup;
|
||||
namespace Sylius\Behat\Element\Admin\CustomerGroup;
|
||||
|
||||
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface;
|
||||
use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface;
|
||||
|
||||
interface UpdatePageInterface extends BaseUpdatePageInterface
|
||||
interface FormElementInterface extends BaseFormElementInterface
|
||||
{
|
||||
public function nameIt(string $name): void;
|
||||
|
||||
public function isCodeDisabled(): bool;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\CustomerGroup;
|
||||
|
||||
use Sylius\Behat\Behaviour\NamesIt;
|
||||
use Sylius\Behat\Behaviour\SpecifiesItsField;
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
|
||||
|
||||
class CreatePage extends BaseCreatePage implements CreatePageInterface
|
||||
{
|
||||
use SpecifiesItsField;
|
||||
use NamesIt;
|
||||
|
||||
protected function getDefinedElements(): array
|
||||
{
|
||||
return array_merge(parent::getDefinedElements(), [
|
||||
'code' => '#sylius_admin_customer_group_code',
|
||||
'name' => '#sylius_admin_customer_group_name',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Behat\Page\Admin\CustomerGroup;
|
||||
|
||||
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface;
|
||||
|
||||
interface CreatePageInterface extends BaseCreatePageInterface
|
||||
{
|
||||
public function specifyCode(string $code): void;
|
||||
|
||||
public function nameIt(string $name): void;
|
||||
}
|
||||
|
|
@ -108,8 +108,8 @@
|
|||
<service id="sylius.behat.context.ui.admin.managing_customer_groups" class="Sylius\Behat\Context\Ui\Admin\ManagingCustomerGroupsContext">
|
||||
<argument type="service" id="sylius.behat.page.admin.customer_group.create" />
|
||||
<argument type="service" id="sylius.behat.page.admin.customer_group.index" />
|
||||
<argument type="service" id="sylius.behat.current_page_resolver" />
|
||||
<argument type="service" id="sylius.behat.page.admin.customer_group.update" />
|
||||
<argument type="service" id="sylius.behat.element.admin.customer_group.form" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.behat.context.ui.admin.managing_exchange_rates" class="Sylius\Behat\Context\Ui\Admin\ManagingExchangeRatesContext">
|
||||
|
|
|
|||
|
|
@ -144,5 +144,12 @@
|
|||
parent="sylius.behat.element.admin.crud.form"
|
||||
>
|
||||
</service>
|
||||
|
||||
<service
|
||||
id="sylius.behat.element.admin.customer_group.form"
|
||||
class="Sylius\Behat\Element\Admin\CustomerGroup\FormElement"
|
||||
parent="sylius.behat.element.admin.crud.form"
|
||||
>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<parameters>
|
||||
<parameter key="sylius.behat.page.admin.customer_group.create.class">Sylius\Behat\Page\Admin\CustomerGroup\CreatePage</parameter>
|
||||
<parameter key="sylius.behat.page.admin.customer_group.create.class">%sylius.behat.page.admin.crud.create.class%</parameter>
|
||||
<parameter key="sylius.behat.page.admin.customer_group.index.class">%sylius.behat.page.admin.crud.index.class%</parameter>
|
||||
<parameter key="sylius.behat.page.admin.customer_group.update.class">Sylius\Behat\Page\Admin\CustomerGroup\UpdatePage</parameter>
|
||||
<parameter key="sylius.behat.page.admin.customer_group.update.class">%sylius.behat.page.admin.crud.update.class%</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ twig_hooks:
|
|||
template: '@SyliusAdmin/shared/crud/common/content/flashes.html.twig'
|
||||
header:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/header.html.twig'
|
||||
form_error_alert:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form_error_alert.html.twig'
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ twig_hooks:
|
|||
template: '@SyliusAdmin/shared/crud/common/content/flashes.html.twig'
|
||||
header:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/header.html.twig'
|
||||
form_error_alert:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form_error_alert.html.twig'
|
||||
form:
|
||||
template: '@SyliusAdmin/shared/crud/common/content/form.html.twig'
|
||||
configuration:
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
<div class="container-xl" {{ attributes }}>
|
||||
{{ form_start(form, {'attr': {'novalidate': 'novalidate', 'id': form.vars.id}}) }}
|
||||
{{ form_errors(form) }}
|
||||
<div class="grid gap-4">
|
||||
{% if hookable_metadata.configuration.method is defined %}
|
||||
<input type="hidden" name="_method" value="{{ hookable_metadata.configuration.method }}" />
|
||||
{% endif %}
|
||||
{{ form_errors(form) }}
|
||||
{{ form_widget(form._token) }}
|
||||
|
||||
{% hook 'form' with { form } %}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %}
|
||||
|
||||
{% set form = hookable_metadata.context.form|default(null) %}
|
||||
|
||||
{% if form is not null and form.vars.valid == false %}
|
||||
<div class="container-xl">
|
||||
<div class="sylius alert alert-danger" role="alert" {{ sylius_test_html_attribute('form-error-alert') }}>
|
||||
<div class="d-flex">
|
||||
<div>{{ icon({ icon: 'danger' }) }}</div>
|
||||
<div class="mx-2">
|
||||
<h4 class="alert-title">{{ 'sylius.ui.error'|trans }}</h4>
|
||||
<div class="text-secondary">{{ 'sylius.ui.this_message_contains_errors'|trans }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
Loading…
Add table
Reference in a new issue