diff --git a/.bunnyshell/docker/php/Dockerfile b/.bunnyshell/docker/php/Dockerfile index 06f13595c9..fff612c6d2 100644 --- a/.bunnyshell/docker/php/Dockerfile +++ b/.bunnyshell/docker/php/Dockerfile @@ -6,6 +6,7 @@ ARG NODE_VERSION=20 ARG ALPINE_VERSION=3.18 ARG COMPOSER_VERSION=2.6 ARG PHP_EXTENSION_INSTALLER_VERSION=latest +ARG DATABASE_URL FROM composer:${COMPOSER_VERSION} AS composer @@ -13,6 +14,8 @@ FROM mlocati/php-extension-installer:${PHP_EXTENSION_INSTALLER_VERSION} AS php_e FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS base +ENV DATABASE_URL=${DATABASE_URL} + # persistent / runtime deps RUN apk add --no-cache \ acl \ @@ -89,20 +92,23 @@ RUN set -eux; \ g++ \ gcc \ make \ + git \ ; # prevent the reinstallation of vendors at every changes in the source code -COPY package.json yarn.* ./ -RUN set -eux; \ - yarn install; \ - yarn cache clean +COPY package.json package-*.json ./ COPY --from=base /srv/sylius/src/Sylius/Bundle/UiBundle/Resources/private src/Sylius/Bundle/UiBundle/Resources/private/ -COPY --from=base /srv/sylius/src/Sylius/Bundle/AdminBundle/Resources/private src/Sylius/Bundle/AdminBundle/Resources/private/ +COPY --from=base /srv/sylius/src/Sylius/Bundle/AdminBundle src/Sylius/Bundle/AdminBundle/ COPY --from=base /srv/sylius/src/Sylius/Bundle/ShopBundle/Resources/private src/Sylius/Bundle/ShopBundle/Resources/private/ +COPY --from=base /srv/sylius/vendor/symfony/ux-autocomplete/assets vendor/symfony/ux-autocomplete/assets/ +COPY --from=base /srv/sylius/vendor/symfony/ux-live-component/assets vendor/symfony/ux-live-component/assets/ + +RUN set -eux; \ + npm install; COPY webpack.config.js ./ -RUN yarn build:prod +RUN npm run build:prod FROM base AS sylius_php_prod diff --git a/.bunnyshell/templates/preview/bunnyshell.yaml b/.bunnyshell/templates/preview/bunnyshell.yaml index 94b32cbff0..ab45339670 100644 --- a/.bunnyshell/templates/preview/bunnyshell.yaml +++ b/.bunnyshell/templates/preview/bunnyshell.yaml @@ -43,6 +43,8 @@ components: context: . dockerfile: .bunnyshell/docker/php/Dockerfile target: sylius_php_prod + args: + DATABASE_URL: 'mysql://{{ env.vars.MYSQL_USER }}:{{ env.vars.MYSQL_PASSWORD }}@database/{{ env.vars.MYSQL_DATABASE }}?serverVersion=8.0' command: php-fpm entrypoint: /usr/local/bin/php-entrypoint environment: diff --git a/composer-require-checker.json b/composer-require-checker.json index 2643132571..b4c8f81b7a 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -89,6 +89,7 @@ "Psr\\Container\\ContainerInterface", "Psr\\Http\\Message\\RequestFactoryInterface", "Psr\\Http\\Message\\StreamFactoryInterface", + "Sylius\\Bundle\\UiBundle\\Registry\\TemplateBlockRegistryInterface", "Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface" ], "php-core-extensions" : [ diff --git a/composer.json b/composer.json index a9dbaa3c74..4c2d3f7c2d 100644 --- a/composer.json +++ b/composer.json @@ -87,11 +87,12 @@ "sylius/resource": "^1.10", "sylius/resource-bundle": "^1.10", "sylius/theme-bundle": "^2.3", + "sylius/twig-hooks": "~0.2.4", "symfony/asset": "^6.4.0", + "symfony/cache-contracts": "^2.5 || ^3.0", "symfony/clock": "^6.4.0", "symfony/config": "^6.4.0", "symfony/console": "^6.4.1", - "symfony/cache-contracts": "^2.5 || ^3.0", "symfony/dependency-injection": "^6.4.1", "symfony/deprecation-contracts": "^3.1", "symfony/doctrine-bridge": "^6.4.0", @@ -125,17 +126,24 @@ "symfony/security-http": "^6.4.0", "symfony/serializer": "^6.4.0", "symfony/service-contracts": "^2.5 || ^3.0", + "symfony/stimulus-bundle": "^2.12", "symfony/string": "^6.4.0", "symfony/templating": "^6.4.0", "symfony/translation": "^6.4.0", "symfony/translation-contracts": "^3.3", "symfony/twig-bundle": "^6.4.0", + "symfony/ux-autocomplete": "^2.17", + "symfony/ux-live-component": "^2.17", + "symfony/ux-twig-component": "^2.17", "symfony/validator": "^6.4.0", "symfony/webpack-encore-bundle": "^1.17.1", "symfony/workflow": "^6.4.0", "symfony/yaml": "^6.4.0", - "twig/intl-extra": "^2.12 || ^3.4", - "twig/twig": "^2.12 || ^3.3", + "symfonycasts/dynamic-forms": "v0.1.1", + "twig/extra-bundle": "~3.8.0", + "twig/intl-extra": "~3.8.0", + "twig/string-extra": "~3.8.0", + "twig/twig": "~3.8.0", "webmozart/assert": "^1.9", "willdurand/hateoas": "^3.0", "willdurand/hateoas-bundle": "^2.0", @@ -188,8 +196,7 @@ "conflict": { "api-platform/core": "2.7.17", "doctrine/orm": ">= 2.16.0", - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "3.9.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "behat/behat": "^3.6.1", diff --git a/config/bundles.php b/config/bundles.php index a721c9c598..34025408e7 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -59,4 +59,10 @@ return [ SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], + Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], + Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true], + Sylius\TwigHooks\TwigHooksBundle::class => ['all' => true], + Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true], + Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], ]; diff --git a/config/packages/_sylius.yaml b/config/packages/_sylius.yaml index deef9ce200..663f65eff9 100644 --- a/config/packages/_sylius.yaml +++ b/config/packages/_sylius.yaml @@ -1,12 +1,12 @@ imports: - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" } - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" } + - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } + - { resource: "../parameters.yaml" } parameters: diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index 8545473ddd..3b315dcc15 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -2,11 +2,3 @@ twig: paths: ['%kernel.project_dir%/templates'] debug: '%kernel.debug%' strict_variables: '%kernel.debug%' - -services: - _defaults: - public: false - autowire: true - autoconfigure: true - - Twig\Extra\Intl\IntlExtension: ~ diff --git a/config/routes/ux_live_component.yaml b/config/routes/ux_live_component.yaml new file mode 100644 index 0000000000..e56523abfb --- /dev/null +++ b/config/routes/ux_live_component.yaml @@ -0,0 +1,5 @@ +live_component: + resource: '@LiveComponentBundle/config/routes.php' + prefix: '/_components' + # adjust prefix to add localization to your components + #prefix: '/{_locale}/_components' diff --git a/features/admin/addressing/managing_countries/adding_country.feature b/features/admin/addressing/managing_countries/adding_country.feature index 37e5b6a1b7..513893b38d 100644 --- a/features/admin/addressing/managing_countries/adding_country.feature +++ b/features/admin/addressing/managing_countries/adding_country.feature @@ -7,7 +7,7 @@ Feature: Adding a new country Background: Given I am logged in as an administrator - @ui @api + @api @ui Scenario: Adding country When I want to add a new country And I choose "United States" diff --git a/features/admin/addressing/managing_countries/adding_country_with_provinces.feature b/features/admin/addressing/managing_countries/adding_country_with_provinces.feature index 5986d02e2d..ad44751123 100644 --- a/features/admin/addressing/managing_countries/adding_country_with_provinces.feature +++ b/features/admin/addressing/managing_countries/adding_country_with_provinces.feature @@ -7,7 +7,7 @@ Feature: Adding countries with provinces Background: Given I am logged in as an administrator - @ui @javascript @api + @api @ui @javascript Scenario: Adding a country with a province When I want to add a new country And I choose "United Kingdom" @@ -17,7 +17,7 @@ Feature: Adding countries with provinces And the country "United Kingdom" should appear in the store And the country "United Kingdom" should have the "Scotland" province - @ui @javascript @api + @api @ui @javascript Scenario: Adding a country with two provinces When I want to add a new country And I choose "United Kingdom" diff --git a/features/admin/addressing/managing_countries/country_validation.feature b/features/admin/addressing/managing_countries/country_validation.feature index 9815e50c69..b9813ad67c 100644 --- a/features/admin/addressing/managing_countries/country_validation.feature +++ b/features/admin/addressing/managing_countries/country_validation.feature @@ -8,7 +8,7 @@ Feature: Country validation Given the store operates in "Norway" And I am logged in as an administrator - @ui @api + @api @ui Scenario: Trying to add a new country with used code When I want to add a new country Then I should not be able to choose "Norway" diff --git a/features/admin/addressing/managing_countries/editing_country.feature b/features/admin/addressing/managing_countries/editing_country.feature index fe3c162bf3..b65a785917 100644 --- a/features/admin/addressing/managing_countries/editing_country.feature +++ b/features/admin/addressing/managing_countries/editing_country.feature @@ -7,7 +7,7 @@ Feature: Editing country Background: Given I am logged in as an administrator - @ui @api + @api @ui Scenario: Disabling country Given the store has country "United States" When I want to edit this country @@ -16,7 +16,7 @@ Feature: Editing country Then I should be notified that it has been successfully edited And this country should be disabled - @ui @api + @api @ui Scenario: Enabling country Given the store has disabled country "United States" When I want to edit this country @@ -25,7 +25,7 @@ Feature: Editing country Then I should be notified that it has been successfully edited And this country should be enabled - @ui @api + @api @ui Scenario: Seeing disabled code field while editing country Given the store has country "United States" When I want to edit this country diff --git a/features/admin/addressing/managing_countries/managing_provinces_of_country.feature b/features/admin/addressing/managing_countries/managing_provinces_of_country.feature index 54e48630db..cc143c7cf0 100644 --- a/features/admin/addressing/managing_countries/managing_provinces_of_country.feature +++ b/features/admin/addressing/managing_countries/managing_provinces_of_country.feature @@ -8,7 +8,7 @@ Feature: Managing provinces of a country Given the store has country "United Kingdom" And I am logged in as an administrator - @ui @javascript @api + @api @ui @javascript Scenario: Adding a province to an existing country When I want to edit this country And I add the "Scotland" province with "GB-SCT" code @@ -16,7 +16,7 @@ Feature: Managing provinces of a country Then I should be notified that it has been successfully edited And this country should have the "Scotland" province - @ui @javascript @api + @api @ui @javascript Scenario: Removing a province from an existing country Given this country has the "Northern Ireland" province with "GB-NIR" code When I want to edit this country @@ -25,7 +25,7 @@ Feature: Managing provinces of a country Then I should be notified that it has been successfully edited And this country should not have the "Northern Ireland" province - @ui @javascript @api + @api @ui @javascript Scenario: Removing a province that is a zone member should not be possible Given this country has the "Northern Ireland" province with "GB-NIR" code And this country also has the "Scotland" province with "GB-SCT" code @@ -43,7 +43,7 @@ Feature: Managing provinces of a country And this country should still have the "Scotland" province And this country should still have the "England" province - @ui @javascript @api + @api @ui @javascript Scenario: Removing a province that is not a zone member anymore should be possible Given this country has the "Northern Ireland" province with "GB-NIR" code And this country also has the "Scotland" province with "GB-SCT" code @@ -60,18 +60,18 @@ Feature: Managing provinces of a country And this country should not have the "England" province And this country should still have the "Northern Ireland" and "Scotland" provinces - @ui @javascript @api + @api @ui @javascript Scenario: Removing and adding a new province to an existing country Given this country has the "Northern Ireland" province with "GB-NIR" code When I want to edit this country - And I delete the "Northern Ireland" province of this country And I add the "Scotland" province with "GB-SCT" code + And I delete the "Northern Ireland" province of this country And I save my changes Then I should be notified that it has been successfully edited And this country should not have the "Northern Ireland" province And this country should have the "Scotland" province - @ui @javascript @api + @api @ui @javascript Scenario: Adding a province with an austrian province code When I want to edit this country And I add the "Wien" province with "AT-9" code diff --git a/features/admin/addressing/managing_countries/province_unique_fields_validation.feature b/features/admin/addressing/managing_countries/province_unique_fields_validation.feature index 6c10b40638..51bc65c210 100644 --- a/features/admin/addressing/managing_countries/province_unique_fields_validation.feature +++ b/features/admin/addressing/managing_countries/province_unique_fields_validation.feature @@ -9,7 +9,7 @@ Feature: Province unique fields validation And this country has the "Northern Ireland" province with "GB-NIR" code And I am logged in as an administrator - @ui @javascript @api + @api @ui @javascript Scenario: Trying to add a new province with a taken code When I want to add a new country And I choose "Gibraltar" @@ -17,14 +17,14 @@ Feature: Province unique fields validation And I try to add it Then I should be notified that province code must be unique - @ui @javascript @api + @api @ui @javascript Scenario: Trying to add a new province with a taken name When I want to edit this country And I add the "Northern Ireland" province with "GB-NI" code And I save my changes Then I should be notified that province name must be unique - @ui @javascript @api + @api @ui @javascript Scenario: Trying to add new provinces with duplicated codes When I want to edit this country And I add the "Scotland" province with "GB-SCO" code @@ -32,7 +32,7 @@ Feature: Province unique fields validation And I save my changes Then I should be notified that all province codes and names within this country need to be unique - @ui @javascript @api + @api @ui @javascript Scenario: Trying to add new provinces with duplicated names When I want to edit this country And I add the "Scotland" province with "GB-SC" code diff --git a/features/admin/addressing/managing_countries/province_validation.feature b/features/admin/addressing/managing_countries/province_validation.feature index 9f9567157b..d064c157a1 100644 --- a/features/admin/addressing/managing_countries/province_validation.feature +++ b/features/admin/addressing/managing_countries/province_validation.feature @@ -8,7 +8,7 @@ Feature: Province validation Given the store has country "United Kingdom" And I am logged in as an administrator - @ui @javascript @api + @api @ui @javascript Scenario: Trying to add a new province without specifying its code When I want to create a new province in country "United Kingdom" And I name the province "Scotland" @@ -17,7 +17,7 @@ Feature: Province validation Then I should be notified that code is required And province with name "Scotland" should not be added in this country - @ui @mink:chromedriver @api + @api @ui @mink:chromedriver Scenario: Trying to add a new province with a too long code When I want to create a new province in country "United Kingdom" And I name the province "Scotland" @@ -25,7 +25,7 @@ Feature: Province validation And I try to save my changes Then I should be informed that the provided province code is too long - @ui @javascript @api + @api @ui @javascript Scenario: Trying to add a new province without specifying its name When I want to create a new province in country "United Kingdom" And I specify the province code as "GB-SCT" @@ -34,7 +34,7 @@ Feature: Province validation Then I should be notified that name is required And province with code "GB-SCT" should not be added in this country - @ui @javascript @api + @api @ui @javascript Scenario: Trying to remove name from an existing province Given this country has the "Northern Ireland" province with "GB-NIR" code When I want to edit this country diff --git a/features/admin/addressing/managing_zones/adding_zone.feature b/features/admin/addressing/managing_zones/adding_zone.feature index 75c2020553..3ceaec5580 100644 --- a/features/admin/addressing/managing_zones/adding_zone.feature +++ b/features/admin/addressing/managing_zones/adding_zone.feature @@ -12,7 +12,7 @@ Feature: Adding a new zone with country type members And the store has a zone "North America" with code "NA" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a zone with a country type member When I want to create a new zone consisting of country And I name it "European Union" @@ -32,7 +32,7 @@ Feature: Adding a new zone with country type members Then I should be notified that it has been successfully created And the zone named "United States" with the "Alabama" province member should appear in the registry - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a zone with zone type member When I want to create a new zone consisting of zone And I name it "America" @@ -51,7 +51,7 @@ Feature: Adding a new zone with country type members And I add it Then I should be informed that the provided zone member code is too long - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a zone with a country type member and a shipping scope When I want to create a new zone consisting of country And I name it "European Union" @@ -63,7 +63,7 @@ Feature: Adding a new zone with country type members And the zone named "European Union" with the "France" country member should appear in the registry And its scope should be "shipping" - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding zone with disabled country When I want to create a new zone consisting of country And I name it "European Union" diff --git a/features/admin/addressing/managing_zones/deleting_zone.feature b/features/admin/addressing/managing_zones/deleting_zone.feature index 8b55f202c6..1d61d33416 100644 --- a/features/admin/addressing/managing_zones/deleting_zone.feature +++ b/features/admin/addressing/managing_zones/deleting_zone.feature @@ -23,7 +23,7 @@ Feature: Deleting a zone @ui @api Scenario: Deleting zone with associated tax rates should not be possible When I try to delete the zone named "South America" - Then I should be notified that the zone is in use and cannot be deleted + Then I should be notified that this zone cannot be deleted And I should still see the zone named "South America" in the list @ui @api diff --git a/features/admin/addressing/managing_zones/editing_zone.feature b/features/admin/addressing/managing_zones/editing_zone.feature index b5215e73cb..121eb2e6cb 100644 --- a/features/admin/addressing/managing_zones/editing_zone.feature +++ b/features/admin/addressing/managing_zones/editing_zone.feature @@ -14,7 +14,7 @@ Feature: Editing a zone And the store has a zone "South America" with code "SA" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing a country from a zone Given the store has a zone "European Union" with code "EU" And it has the "France" country member @@ -25,7 +25,7 @@ Feature: Editing a zone Then I should be notified that it has been successfully edited And this zone should have only the "France" country member - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing and adding countries to a zone Given the store has a zone "European Union" with code "EU" And it has the "Belgium", "France" and "Germany" country members @@ -36,7 +36,7 @@ Feature: Editing a zone Then I should be notified that it has been successfully edited And this zone should have only the "France" country member - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing a province from a zone Given the store has a zone "United States" with code "USA" And it has the "Alabama" province member @@ -47,7 +47,7 @@ Feature: Editing a zone Then I should be notified that it has been successfully edited And this zone should have only the "Alabama" province member - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing a zone from a zone Given the store has a zone "America" with code "AM" And it has the zone named "North America" diff --git a/features/admin/addressing/managing_zones/zone_validation.feature b/features/admin/addressing/managing_zones/zone_validation.feature index 5a1ce21f69..06f1f5e8ce 100644 --- a/features/admin/addressing/managing_zones/zone_validation.feature +++ b/features/admin/addressing/managing_zones/zone_validation.feature @@ -52,19 +52,19 @@ Feature: Zone validation When I want to modify the zone named "European Union" Then I should not be able to edit its code - @ui @api + @ui @api @mink:chromedriver Scenario: Being unable to add itself to members during editing an existing zone Given the store has a zone "European Union" with code "EU" When I want to modify the zone named "European Union" - Then I can not add a zone "European Union" + Then I should not be able to add the "European Union" zone as a member - @ui + @ui @todo-api Scenario: Seeing a disabled type field when adding country type zone When I want to create a new zone consisting of country Then I should not be able to edit its type And it should be of country type - @ui + @ui @todo-api Scenario: Seeing a disabled type field when adding province type zone When I want to create a new zone consisting of province Then I should not be able to edit its type diff --git a/features/admin/being_redirected_to_previous_filtered_page.feature b/features/admin/being_redirected_to_previous_filtered_page.feature index c75a1e5e0f..acf4b6bfd7 100644 --- a/features/admin/being_redirected_to_previous_filtered_page.feature +++ b/features/admin/being_redirected_to_previous_filtered_page.feature @@ -12,7 +12,7 @@ Feature: Being redirected to previous filtered page And the store has a product "Znicz Pruszków T-Shirt" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Being redirected to previous filtered page after deleting a product When I browse products And I choose enabled filter @@ -20,7 +20,7 @@ Feature: Being redirected to previous filtered page And I delete the "FC Barcelona T-Shirt" product on filtered page Then I should be redirected to the previous page of only enabled products - @ui @no-api + @todo @ui @no-api Scenario: Being redirected to previous filtered page after cancelling editing a product When I browse products And I choose enabled filter @@ -29,7 +29,7 @@ Feature: Being redirected to previous filtered page And I cancel my changes Then I should be redirected to the previous page of only enabled products - @ui @no-api + @todo @ui @no-api Scenario: Being redirected to previous filtered page with pagination after cancelling editing a product When I browse products And I choose enabled filter @@ -39,7 +39,7 @@ Feature: Being redirected to previous filtered page And I cancel my changes Then I should be redirected to the 2nd page of only enabled products - @ui @no-api + @todo @ui @no-api Scenario: Being redirected to previous filtered page after cancelling creating a new product When I browse products And I choose enabled filter diff --git a/features/admin/blocking_login_for_disabled_administrators.feature b/features/admin/blocking_login_for_disabled_administrators.feature index 584ffa8cdc..9d332cafe3 100644 --- a/features/admin/blocking_login_for_disabled_administrators.feature +++ b/features/admin/blocking_login_for_disabled_administrators.feature @@ -8,7 +8,7 @@ Feature: Blocking login for disabled administrators Given the store operates on a single channel in "United States" And there is an administrator "admin@example.com" identified by "sylius" - @ui @api + @todo @ui @api Scenario: Sign in with email and password Given this administrator account is disabled And I want to log in @@ -17,7 +17,7 @@ Feature: Blocking login for disabled administrators And I log in Then I should not be logged in - @ui @api + @todo @ui @api Scenario: Revoking the access while administrator is logged in Given I am logged in as "admin@example.com" administrator When this administrator account becomes disabled diff --git a/features/admin/browsing_administration_panel_in_proper_language.feature b/features/admin/browsing_administration_panel_in_proper_language.feature index 105801348e..69391451da 100644 --- a/features/admin/browsing_administration_panel_in_proper_language.feature +++ b/features/admin/browsing_administration_panel_in_proper_language.feature @@ -11,14 +11,14 @@ Feature: Browsing administration panel in a proper locale And I am logged in as an administrator And I am using "Polish (Poland)" locale for my panel - @ui + @todo @ui Scenario: Getting errors in my language Given I am editing my details When I change its email to "wrong-email" And I save my changes Then I should be notified that this email is not valid in "Polish (Poland)" locale - @ui + @todo @ui Scenario: Seeing menu in my language When I open administration dashboard Then I should see sidebar catalog section configuration in "Polish (Poland)" locale diff --git a/features/admin/channel/managing_channels/browsing_channels.feature b/features/admin/channel/managing_channels/browsing_channels.feature index 070993551b..6e86bf99e7 100644 --- a/features/admin/channel/managing_channels/browsing_channels.feature +++ b/features/admin/channel/managing_channels/browsing_channels.feature @@ -9,7 +9,7 @@ Feature: Browsing channels And the store operates on another channel named "Mobile Channel" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Browsing defined channels When I want to browse channels Then I should see 2 channels in the list diff --git a/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature b/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature index bd44a3db81..8ac94e83ac 100644 --- a/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature +++ b/features/admin/channel/managing_channels/choosing_required_address_in_checkout_for_channel.feature @@ -8,7 +8,7 @@ Feature: Choosing a required address in the checkout for a channel Given the store operates on a single channel in "United States" And I am logged in as an administrator - @api @ui + @api @ui @mink:chromedriver Scenario: Adding a new channel with a required address in the checkout When I want to create a new channel And I specify its code as "MOBILE" @@ -22,7 +22,7 @@ Feature: Choosing a required address in the checkout for a channel Then I should be notified that it has been successfully created And the required address in the checkout for this channel should be shipping - @api @ui + @api @ui @mink:chromedriver Scenario: Changing a required address in the checkout for an existing channel Given the store operates on a channel named "Web Store" When I want to modify this channel diff --git a/features/admin/channel/managing_channels/deleting_channel.feature b/features/admin/channel/managing_channels/deleting_channel.feature index fb2976984b..727561480f 100644 --- a/features/admin/channel/managing_channels/deleting_channel.feature +++ b/features/admin/channel/managing_channels/deleting_channel.feature @@ -9,7 +9,7 @@ Feature: Deleting a channel And the store operates on another channel named "Mobile Store" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Deleted channel should disappear from the registry When I delete channel "Web Store" Then I should be notified that it has been successfully deleted diff --git a/features/admin/channel/managing_channels/deleting_multiple_channels.feature b/features/admin/channel/managing_channels/deleting_multiple_channels.feature index 5346dc8041..7cef25afa2 100644 --- a/features/admin/channel/managing_channels/deleting_multiple_channels.feature +++ b/features/admin/channel/managing_channels/deleting_multiple_channels.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple channels And the store operates on another channel named "DE Store" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple channels at once When I browse channels And I check the "PL Store" channel diff --git a/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature b/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature index 97bc83dfe4..e1396a5e6e 100644 --- a/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature +++ b/features/admin/channel/managing_channels/editing_menu_taxon_on_channel.feature @@ -11,7 +11,7 @@ Feature: Editing menu taxon on channel And channel "Web Store" has menu taxon "Clothes" And I am logged in as an administrator - @todo @api @ui @javascript + @todo @api @ui @mink:chromedriver Scenario: Editing menu taxon on the channel When I want to modify a channel "Web Store" And I change its menu taxon to "Guns" diff --git a/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature b/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature index 1c5641c89b..dde0b927fa 100644 --- a/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature +++ b/features/admin/channel/managing_channels/excluding_chosen_taxons_from_showing_lowest_price_of_discounted_products.feature @@ -9,7 +9,7 @@ Feature: Excluding chosen taxons from displaying the lowest price of discounted And the store classifies its products as "T-Shirts", "Caps" and "Sweaters" And I am logged in as an administrator - @no-api @ui @javascript + @no-api @ui @mink:chromedriver Scenario: Excluding a singular taxon from displaying the lowest price of discounted products When I want to modify a channel "Poland" And I exclude the "T-Shirts" taxon from showing the lowest price of discounted products diff --git a/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature b/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature index f46c66cb40..575a75bce6 100644 --- a/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature +++ b/features/admin/channel/managing_channels/not_being_able_to_delete_last_available_channel.feature @@ -8,7 +8,7 @@ Feature: Not being able to delete a last available channel Given the store operates on a channel named "Web Store" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Preventing from deleting only channel When I delete channel "Web Store" Then I should be notified that it cannot be deleted diff --git a/features/admin/channel/theming/managing_themes_per_channel.feature b/features/admin/channel/theming/managing_themes_per_channel.feature index 2d67624818..25bfea6d60 100644 --- a/features/admin/channel/theming/managing_themes_per_channel.feature +++ b/features/admin/channel/theming/managing_themes_per_channel.feature @@ -9,7 +9,7 @@ Feature: Managing themes per channel And the store has "maverick/meerkat" theme And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: None of the themes are used by default When I create a new channel "Poland" Then that channel should not use any theme diff --git a/features/admin/currency/managing_currencies/adding_currency.feature b/features/admin/currency/managing_currencies/adding_currency.feature index 02c1d63e7c..bc6bf683f8 100644 --- a/features/admin/currency/managing_currencies/adding_currency.feature +++ b/features/admin/currency/managing_currencies/adding_currency.feature @@ -7,7 +7,7 @@ Feature: Adding a new currency Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new currency When I want to add a new currency And I choose "Euro" diff --git a/features/admin/currency/managing_currencies/browsing_currencies.feature b/features/admin/currency/managing_currencies/browsing_currencies.feature index 52c15f613e..2f0d23a0b3 100644 --- a/features/admin/currency/managing_currencies/browsing_currencies.feature +++ b/features/admin/currency/managing_currencies/browsing_currencies.feature @@ -8,7 +8,7 @@ Feature: Browsing currencies Given the store has currency "Euro", "British Pound" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing currencies in store When I want to browse currencies of the store Then I should see 2 currencies in the list diff --git a/features/admin/currency/managing_currencies/currency_unique_code_validation.feature b/features/admin/currency/managing_currencies/currency_unique_code_validation.feature index f9049e36a3..bb0bda4ccb 100644 --- a/features/admin/currency/managing_currencies/currency_unique_code_validation.feature +++ b/features/admin/currency/managing_currencies/currency_unique_code_validation.feature @@ -8,7 +8,7 @@ Feature: Currency unique code validation Given the store has currency "Euro" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add currency with taken code When I want to add a new currency And I choose "Euro" diff --git a/features/admin/currency/managing_currencies/editing_currency.feature b/features/admin/currency/managing_currencies/editing_currency.feature index 060be02b8a..37934d7e0e 100644 --- a/features/admin/currency/managing_currencies/editing_currency.feature +++ b/features/admin/currency/managing_currencies/editing_currency.feature @@ -7,7 +7,7 @@ Feature: Editing a currency Background: Given I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled code field while editing currency Given the store has currency "Euro" When I want to edit this currency diff --git a/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature b/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature index 415cb6a198..f992de7e2d 100644 --- a/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature +++ b/features/admin/currency/managing_exchange_rates/adding_exchange_rate.feature @@ -8,7 +8,7 @@ Feature: Adding a new exchange rate Given the store has currency "US Dollar" and "British Pound" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new exchange rate When I want to add a new exchange rate And I specify its ratio as 1.20 diff --git a/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature b/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature index 9282b222ee..daa799a791 100644 --- a/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature +++ b/features/admin/currency/managing_exchange_rates/browsing_exchange_rates.feature @@ -10,7 +10,7 @@ Feature: Browsing exchange rates And the exchange rate of "British Pound" to "Bhutanese Ngultrum" is 2.37 And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing store's exchange rates When I am browsing exchange rates of the store Then I should see 2 exchange rates on the list diff --git a/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature b/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature index 4a8651e339..2f5b80fd8f 100644 --- a/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature +++ b/features/admin/currency/managing_exchange_rates/deleting_exchange_rate.feature @@ -8,7 +8,7 @@ Feature: Deleting exchange rates Given the store has currency "US Dollar", "British Pound" and "Bhutanese Ngultrum" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted exchange rate should disappear from the list Given the exchange rate of "US Dollar" to "British Pound" is 1.2 When I delete the exchange rate between "US Dollar" and "British Pound" diff --git a/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature b/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature index 2594303eb9..bc6f7e61e9 100644 --- a/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature +++ b/features/admin/currency/managing_exchange_rates/deleting_multiple_exchange_rates.feature @@ -11,7 +11,7 @@ Feature: Deleting multiple exchange rates And the exchange rate of "Polish Zloty" to "Euro" is 0.22 And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple exchange rates at once When I browse exchange rates And I check the exchange rate between "Euro" and "British Pound" diff --git a/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature b/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature index 2de7ea381b..7b2f42a082 100644 --- a/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature +++ b/features/admin/currency/managing_exchange_rates/editing_exchange_rate.feature @@ -8,7 +8,7 @@ Feature: Editing exchange rate Given the store has currency "US Dollar" and "British Pound" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Change exchange rate's ratio Given the exchange rate of "US Dollar" to "British Pound" is 1.30 And I am editing this exchange rate @@ -17,7 +17,7 @@ Feature: Editing exchange rate Then I should be notified that it has been successfully edited And it should have a ratio of 3.21 - @ui @api + @todo @ui @api Scenario: Being unable to change currencies Given the exchange rate of "US Dollar" to "British Pound" is 1.30 When I want to edit this exchange rate diff --git a/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature b/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature index bc963a76bb..968bbb8601 100644 --- a/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature +++ b/features/admin/currency/managing_exchange_rates/exchange_rate_validation.feature @@ -8,7 +8,7 @@ Feature: Exchange rate validation Given the store has currency "US Dollar" and "British Pound" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new exchange rate without ratio When I want to add a new exchange rate And I choose "US Dollar" as the source currency @@ -18,7 +18,7 @@ Feature: Exchange rate validation Then I should be notified that ratio is required And the exchange rate between "US Dollar" and "British Pound" should not be added - @ui @api + @todo @ui @api Scenario: Trying to add a new exchange rate with negative ratio When I want to add a new exchange rate And I choose "US Dollar" as the source currency @@ -28,7 +28,7 @@ Feature: Exchange rate validation Then I should be notified that the ratio must be greater than zero And the exchange rate between "US Dollar" and "British Pound" should not be added - @ui @api + @todo @ui @api Scenario: Trying to add a new exchange rate with same target currency as source When I want to add a new exchange rate And I specify its ratio as 1.23 diff --git a/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature b/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature index 536703841d..e64bc8874e 100644 --- a/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature +++ b/features/admin/currency/managing_exchange_rates/filtering_exchange_rates_by_currency.feature @@ -11,7 +11,7 @@ Feature: Filtering exchange rates by a currency And the exchange rate of "Polish Zloty" to "Euro" is 0.22 And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering exchange rates by a chosen currency When I browse exchange rates of the store And I choose "Euro" as a currency filter diff --git a/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature b/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature index 886f43f450..5ced3e9125 100644 --- a/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature +++ b/features/admin/currency/managing_exchange_rates/inability_of_adding_exchange_rate_with_same_currency_pair.feature @@ -9,7 +9,7 @@ Feature: Inability of adding exchange rates with the same currency pair And the exchange rate of "Euro" to "British Pound" is 1.2 And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Being prevented from adding an exchange rate for the same currency pair When I want to add a new exchange rate And I specify its ratio as 3.20 @@ -20,7 +20,7 @@ Feature: Inability of adding exchange rates with the same currency pair And I should still see one exchange rate on the list And this exchange rate should have a ratio of 1.2 - @ui @api + @todo @ui @api Scenario: Being prevented from adding an exchange rate for a reversed currency pair When I want to add a new exchange rate And I specify its ratio as 3.20 diff --git a/features/admin/inventory/managing_inventory/browsing_inventory.feature b/features/admin/inventory/managing_inventory/browsing_inventory.feature index db1e3668fa..6fe11d0ca8 100644 --- a/features/admin/inventory/managing_inventory/browsing_inventory.feature +++ b/features/admin/inventory/managing_inventory/browsing_inventory.feature @@ -13,12 +13,12 @@ Feature: Browsing inventory And there are 5 units of product "Iron Maiden T-Shirt" available in the inventory And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Browsing only tracked product variants in the store When I want to browse inventory Then I should see only one tracked variant in the list - @ui @no-api + @todo @ui @no-api Scenario: Being informed about on hand quantity of a product variant When I want to browse inventory Then I should see that the "Iron Maiden T-Shirt" variant has 5 quantity on hand diff --git a/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature b/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature index a2e2445fe5..aa3fb8d494 100644 --- a/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature +++ b/features/admin/inventory/managing_inventory/filtering_inventory_by_code.feature @@ -14,7 +14,7 @@ Feature: Filtering inventory by code And there are 25 units of product "RHCP T-Shirt" available in the inventory And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Filtering tracked product variants by code When I want to browse inventory And I filter tracked variants with code containing "iron" diff --git a/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature b/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature index 619ed89062..485339a3b6 100644 --- a/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature +++ b/features/admin/inventory/managing_inventory/filtering_inventory_by_name.feature @@ -14,7 +14,7 @@ Feature: Filtering inventory by name And there are 25 units of product "RHCP T-Shirt" available in the inventory And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Filtering tracked product variants by name When I want to browse inventory And I filter tracked variants with name containing "RHCP" diff --git a/features/admin/locale/channel_independent_translatable_entities_locales.feature b/features/admin/locale/channel_independent_translatable_entities_locales.feature index 6d6d22b4b4..a48591c9f0 100644 --- a/features/admin/locale/channel_independent_translatable_entities_locales.feature +++ b/features/admin/locale/channel_independent_translatable_entities_locales.feature @@ -10,7 +10,7 @@ Feature: Channel independent translatable entities locales And it uses the "English (United States)" locale by default And I am logged in as an administrator - @ui + @todo @ui Scenario: Using all locales to translate an entity Given the store has locale "German (Germany)" When I want to create a new translatable entity diff --git a/features/admin/locale/managing_locales/adding_locale.feature b/features/admin/locale/managing_locales/adding_locale.feature index f3921f5672..1359deded4 100644 --- a/features/admin/locale/managing_locales/adding_locale.feature +++ b/features/admin/locale/managing_locales/adding_locale.feature @@ -7,7 +7,7 @@ Feature: Adding a new locale Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new locale When I want to create a new locale And I choose Norwegian diff --git a/features/admin/locale/managing_locales/locale_unique_code_validation.feature b/features/admin/locale/managing_locales/locale_unique_code_validation.feature index 1d6ffe0ba0..58f996bd1a 100644 --- a/features/admin/locale/managing_locales/locale_unique_code_validation.feature +++ b/features/admin/locale/managing_locales/locale_unique_code_validation.feature @@ -8,7 +8,7 @@ Feature: Locale unique code validation Given the store has locale "Norwegian (Norway)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add new locale with used code When I want to add a new locale Then I should not be able to choose "Norwegian (Norway)" diff --git a/features/admin/locale/managing_locales/removing_locale.feature b/features/admin/locale/managing_locales/removing_locale.feature index 233251437e..941ee53fe4 100644 --- a/features/admin/locale/managing_locales/removing_locale.feature +++ b/features/admin/locale/managing_locales/removing_locale.feature @@ -10,7 +10,7 @@ Feature: Removing locales And it uses the "English (United States)" locale by default And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleting unused locale Given the store has a product "T-Shirt banana" And this product is named "Banana T-Shirt with Minions" in the "English (United States)" locale @@ -19,7 +19,7 @@ Feature: Removing locales Then I should be informed that locale "Polish (Poland)" has been deleted And only the "English (United States)" locale should be present in the system - @ui @api + @todo @ui @api Scenario: Deleting a locale in use Given the store has a product "T-Shirt banana" And this product is named "Banana T-Shirt with Minions" in the "English (United States)" locale diff --git a/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature b/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature index 510d8a333d..c9090a105d 100644 --- a/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature +++ b/features/admin/order/managing_orders/browsing_orders/browsing_orders.feature @@ -14,7 +14,7 @@ Feature: Browsing orders And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Seeing a new order in the list When I browse orders Then I should see a single order from customer "john.doe@gmail.com" diff --git a/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature b/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature index 0fcc81f916..b764021ffd 100644 --- a/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature +++ b/features/admin/order/managing_orders/browsing_orders/seeing_orders_currency_on_index.feature @@ -17,7 +17,7 @@ Feature: Seeing the currency in which all orders have been placed And there is a customer "Satin" identified by an email "satin@teamlucifer.com" and a password "pswd" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Seeing an order placed in the base currency Given there is a customer "lucy@teamlucifer.com" that placed an order "#00000666" And the customer bought a single "Angel T-Shirt" diff --git a/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature b/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature index ad3d2ec463..0f80358f5c 100644 --- a/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature +++ b/features/admin/order/managing_orders/browsing_orders/seeing_orders_payment_amount_including_all_fees.feature @@ -17,7 +17,7 @@ Feature: Seeing order's payment amount including all fees And the customer chose "DHL" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Seeing total payment When I view the summary of the order "#00000666" Then it should have 2 items diff --git a/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature b/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature index 3d7dbd8726..5834fe0c5f 100644 --- a/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature +++ b/features/admin/order/managing_orders/browsing_orders/seeing_orders_with_different_currency_on_index.feature @@ -17,7 +17,7 @@ Feature: Seeing orders' total in their currency And there is a customer account "customer@example.com" identified by "sylius" And I am logged in as "customer@example.com" - @ui @api + @todo @ui @api Scenario: List of orders from only one channel Given I changed my current channel to "United States" And I have product "Angel T-Shirt" in the cart @@ -26,7 +26,7 @@ Feature: Seeing orders' total in their currency And I confirm my order Then the administrator should see the order with total "$20.00" in order list - @ui @api + @todo @ui @api Scenario: List of orders from different channels Given I changed my current channel to "United States" And I have product "Angel T-Shirt" in the cart diff --git a/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature b/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature index 9618ec5bc7..e3eb084dd6 100644 --- a/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature +++ b/features/admin/order/managing_orders/browsing_orders/sequential_order_number_generation.feature @@ -17,7 +17,7 @@ Feature: Sequential order number generation And the customer chose "Free" shipping method to "United States" with "Offline" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Verifying that orders has correct numbers When I browse orders Then I should see an order with "#000000001" number diff --git a/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature b/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature index 4af17fe610..383027202b 100644 --- a/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature +++ b/features/admin/order/managing_orders/browsing_orders/sorting_orders_by_number.feature @@ -20,13 +20,13 @@ Feature: Sorting orders by their number And the customer chose "Free" shipping method to "United States" with "Offline" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Orders are sorted by descending numbers by default When I browse orders Then I should see an order with "#000000001" number But the first order should have number "#000000003" - @ui @api + @todo @ui @api Scenario: Changing the number sorting order Given I am browsing orders When I switch the way orders are sorted by number diff --git a/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature b/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature index bcb828f2eb..dc4b87d23d 100644 --- a/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature +++ b/features/admin/order/managing_orders/handling_order_shipment/placing_order_with_shipment.feature @@ -15,7 +15,7 @@ Feature: Shipments are in the state "ready" after checkout And the customer chose "Free" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @api @ui Scenario: Checking shipment state of a placed order When I view the summary of the order "#00000666" Then it should have shipment in state "Ready" diff --git a/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature b/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature index a697dbe5e6..d783e21246 100644 --- a/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature +++ b/features/admin/order/managing_orders/handling_order_shipment/shipping_order.feature @@ -15,7 +15,7 @@ Feature: Shipping an order And the customer chose "Free" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @api @ui Scenario: Finalizing order's shipment Given I view the summary of the order "#00000666" When specify its tracking code as "#00044" @@ -23,13 +23,13 @@ Feature: Shipping an order Then I should be notified that the order has been successfully shipped And it should have shipment in state shipped - @ui @api + @api @ui Scenario: Unable to finalize shipped order's shipment Given this order has already been shipped When I view the summary of the order "#00000666" Then I should not be able to ship this order - @ui @api + @api @ui Scenario: Checking the shipment state of a completed order Given this order has already been shipped When I browse orders diff --git a/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature b/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature index b169b37783..bf5498824d 100644 --- a/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature +++ b/features/admin/order/managing_orders/modifying_billing_address/modifying_billing_address.feature @@ -24,6 +24,17 @@ Feature: Modifying a customer billing address after an order has been placed Then I should be notified that it has been successfully edited And this order should have "Lucifer Morningstar", "Seaside Fwy", "90802", "Los Angeles", "United States" as its billing address + @ui @mink:chromedriver @no-api + Scenario: Being able to choose only provinces of the selected country + Given the store also has country "Poland" + And this country has the "Malopolska" province with "ML" code + And this country has the "Slaskie" province with "SL" code + When I view the summary of the order "#00000001" + And I want to modify a customer's billing address of this order + And I change the billing country to "Poland" + Then I should be able to choose the "Malopolska" province for the billing address + And I should be able to choose the "Slaskie" province for the billing address + @api @ui Scenario: Modifying a customer's billing address when a product's price has been changed Given the product "Suit" changed its price to "$300.00" diff --git a/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature b/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature index a28c49c659..7d894271c6 100644 --- a/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature +++ b/features/admin/order/managing_orders/modifying_shipping_address/modifying_shipping_address.feature @@ -25,6 +25,17 @@ Feature: Modifying a customer shipping address after an order has been placed Then I should be notified that it has been successfully edited And this order should be shipped to "Lucifer Morningstar", "Seaside Fwy", "90802", "Los Angeles", "United States" + @ui @mink:chromedriver @no-api + Scenario: Being able to choose only provinces of the selected country + Given the store also has country "Poland" + And this country has the "Malopolska" province with "ML" code + And this country has the "Slaskie" province with "SL" code + When I view the summary of the order "#00000001" + And I want to modify a customer's shipping address of this order + And I change the shipping country to "Poland" + Then I should be able to choose the "Malopolska" province for the shipping address + And I should be able to choose the "Slaskie" province for the shipping address + @api @ui Scenario: Modifying a customer's shipping address when a product's price has been changed Given the product "Suit" changed its price to "$300.00" diff --git a/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature b/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature index a88a25b0a8..2b97a893ff 100644 --- a/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature +++ b/features/admin/order/managing_orders/order_details/being_unable_to_see_cart.feature @@ -10,7 +10,7 @@ Feature: Being unable to see details of a cart And the customer added "PHP T-Shirt" product to the cart And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Being unable to see the details of a cart When I try to view the summary of the customer's latest cart Then I should be informed that the order does not exist diff --git a/features/admin/order/managing_orders/order_details/seeing_order.feature b/features/admin/order/managing_orders/order_details/seeing_order.feature index 7c16f57baa..583dd97711 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order.feature @@ -16,7 +16,7 @@ Feature: Seeing basic information about an order And the customer chose "Free" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing basic information about an order When I view the summary of the order "#00000666" Then it should have been placed by the customer "lucy@teamlucifer.com" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature index 6dccd07970..73abf338aa 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_discounts.feature @@ -16,7 +16,7 @@ Feature: Seeing aggregated discounts of an order And there is a customer "robin.hood@sherwood.com" that placed an order "#00000006" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing shipping and order promotions, but the shipping promotion is not aggregated in summary's promotion total Given the customer bought 2 "Longbow" products And the customer chose "DHL" shipping method to "United States" with "Cash on Delivery" payment @@ -28,7 +28,7 @@ Feature: Seeing aggregated discounts of an order And the order's shipping total should be "$5.00" And the order's total should be "$285.00" - @api @ui + @api @todo @ui Scenario: Seeing multiple order promotions aggregated in summary Given there is a promotion "Big order discount" And it gives "$70.00" discount to every order with quantity at least 3 diff --git a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature index 07a5a756a6..0520dc1d11 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_aggregated_taxes.feature @@ -20,7 +20,7 @@ Feature: Seeing aggregated taxes of an order And there is a customer "charles.the.great@medieval.com" that placed an order "#00000001" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing aggregated taxes of products and shipping Given the customer bought a single "Composite bow" And the customer chose "DHL" shipping method to "United States" with "Offline" payment @@ -31,7 +31,7 @@ Feature: Seeing aggregated taxes of an order And the order's tax total should be "$25.30" And the order's total should be "$135.30" - @api @ui + @api @todo @ui Scenario: Seeing aggregated taxes of multiple products from different tax rates and shipping Given the customer bought a single "Composite bow" And the customer bought a "Claymore" and a "Bastard sword" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature b/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature index 49c8c6ee23..6aeb3665f6 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_currency_on_show.feature @@ -22,7 +22,7 @@ Feature: Seeing the currency an order has been placed in on it's details page And there is a customer "Satin" identified by an email "satin@teamlucifer.com" and a password "pswd" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: All prices are in the base currency when the client haven't chosen any other Given there is a customer "satin@teamlucifer.com" that placed an order "#00000666" And the customer bought a single "Angel T-Shirt" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature b/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature index 0334feb27f..35505af5df 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_discounts.feature @@ -15,7 +15,7 @@ Feature: Seeing discounts of an order And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing promotion discount on order while buying at least 3 items Given the promotion gives "$15.00" discount to every order with quantity at least 3 And the customer bought 4 "Angel T-Shirt" products @@ -26,7 +26,7 @@ Feature: Seeing discounts of an order And the order's promotion discount should be "-$15.00" from "Holiday promotion" promotion And the order's total should be "$141.00" - @api @ui + @api @todo @ui Scenario: Seeing promotion discount on order's items while buying a product from a promoted taxon Given the promotion gives "$10.00" off on every product classified as "T-Shirts" And the customer bought a single "Angel T-Shirt" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature b/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature index d3c3bf7c8d..12e7a95d2a 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_item_detailed_data.feature @@ -23,7 +23,7 @@ Feature: Seeing order item detailed data And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing details of item in one row Given I view the summary of the order "#00000666" When I check "Marvel T-Shirt" data diff --git a/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature index 5decf0c51f..9cfb987c51 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_item_included_taxes.feature @@ -15,7 +15,7 @@ Feature: Seeing included in price taxes of order items And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing included in price taxes of order items are not counted in taxes total Given the customer bought 2 "Winchester M1866" products And the customer chose "Free" shipping method to "United States" with "Offline" payment diff --git a/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature index 5eb3c596bb..13ec31df08 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_item_taxes.feature @@ -15,7 +15,7 @@ Feature: Seeing taxes of order items And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing taxes of order items Given the customer bought a "PHP T-Shirt" and a "Symfony2 T-Shirt" And the customer chose "Free" shipping method to "United States" with "Offline" payment diff --git a/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature b/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature index 24cc2ca4d1..de41f79d9f 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_items_with_proper_names.feature @@ -15,7 +15,7 @@ Feature: Seeing order items with proper names And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing order items with proper names Given the product "Angel T-Shirt" was renamed to "Devil Cardigan" And the product "Angel Mug" was renamed to "Devil Glass" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature b/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature index ca8313c618..00d2eea7f4 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_new_state_after_customers_checkout.feature @@ -12,7 +12,7 @@ Feature: Placing an order And there is a customer "sylius@example.com" that placed an order "#00000022" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Verifying that order has new state right after checkout Given the customer bought 3 "Iron Maiden T-Shirt" products And the customer chose "Free" shipping method to "United States" with "Offline" payment diff --git a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature index 95d4d9b147..8e41b7a61f 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_free_order_coupon_was_applied.feature @@ -18,7 +18,7 @@ Feature: Seeing payment state as paid after checkout steps if order total is zer And the customer chose "Free" shipping method And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing payment state as paid on orders list When I browse orders Then the order "#00000666" should have order payment state "Paid" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature index fcc8a32250..4b59e914b3 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_payment_state_as_completed_if_order_total_is_zero.feature @@ -16,7 +16,7 @@ Feature: Seeing payment state as paid after checkout steps if order total is zer And the customer chose "Free" shipping method And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing payment state as paid on orders list When I browse orders Then the order "#00000666" should have order payment state "Paid" @@ -26,7 +26,7 @@ Feature: Seeing payment state as paid after checkout steps if order total is zer When I view the summary of the order "#00000666" Then I should be informed that there are no payments - @ui @no-api + @todo @ui @no-api Scenario: Seeing payment state as paid on order's summary When I view the summary of the order "#00000666" Then I should be informed that there are no payments diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature index c97a1e025a..1ee021af6f 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_after_checkout.feature @@ -15,18 +15,18 @@ Feature: Seeing shipping states of an order after checkout steps And the customer chose "Free" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing ready order shipping state When I browse orders Then order "#00000666" should have shipment state "ready" - @api @ui + @api @todo @ui Scenario: Seeing shipped order shipping state Given this order has already been shipped When I browse orders Then order "#00000666" should have shipment state "shipped" - @api @ui + @api @todo @ui Scenario: Seeing cancelled order shipping state Given the customer cancelled this order When I browse orders diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature index 2d3201e533..e1965adb15 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_shipment_state_as_shipped_if_there_is_not_shipments_to_deliver.feature @@ -16,12 +16,12 @@ Feature: Seeing shipping states of an order as shipped if there are no shipments And the customer chose "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing shipping state as shipped on orders list When I browse orders Then the order "#00000666" should have order shipping state "Shipped" - @api @ui + @api @todo @ui Scenario: Seeing shipping state as shipped on order's summary When I view the summary of the order "#00000666" Then it should have order's shipping state "Shipped" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature index 12222dd7ee..37710be38d 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_shipping_fees.feature @@ -14,7 +14,7 @@ Feature: Seeing shipping fees of an order And the customer bought a single "Angel T-Shirt" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing Free shipping of an order Given the customer chose "Free" shipping method to "United States" with "Offline" payment When I view the summary of the order "#00000666" @@ -24,7 +24,7 @@ Feature: Seeing shipping fees of an order And the order's shipping total should be "$0.00" And the order's total should be "$39.00" - @api @ui + @api @todo @ui Scenario: Seeing shipping fee of an order Given the customer chose "DHL" shipping method to "United States" with "Offline" payment When I view the summary of the order "#00000666" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature index 674116b518..6e841f0fb5 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_shipping_taxes.feature @@ -16,7 +16,7 @@ Feature: Seeing taxes of an order And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing taxes of order items and shipping Given the customer bought a single "Symfony2 T-Shirt" And the customer chose "DHL" shipping method to "United States" with "Offline" payment @@ -28,7 +28,7 @@ Feature: Seeing taxes of an order And the order's tax total should be "$34.50" And the order's total should be "$184.50" - @api @ui + @api @todo @ui Scenario: Seeing taxes of items and shipping from paid order Given the customer bought a single "Symfony2 T-Shirt" And the customer chose "DHL" shipping method to "United States" with "Offline" payment diff --git a/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature b/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature index 3afdc47704..b939d93ab2 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_shipping_total_with_applied_promotion_and_taxes.feature @@ -19,7 +19,7 @@ Feature: Seeing shipping total with applied promotion and taxes And the customer bought a single "Gryffindor scarf" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing taxes of order items and shipping with applied promotion Given the customer chose "Owl post" shipping method to "United States" with "Offline" payment When I view the summary of the order "#00000777" @@ -30,7 +30,7 @@ Feature: Seeing shipping total with applied promotion and taxes And the order's tax total should be "$24.15" And the order's total should be "$129.15" - @api @ui + @api @todo @ui Scenario: Seeing taxes of order items and multiple shipments with applied promotion Given the store has "Pigeon post" shipping method with "$16.00" fee within the "US" zone And shipping method "Pigeon post" belongs to "Shipping Services" tax category diff --git a/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature b/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature index 90b6d0e780..2f07c487fb 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_with_different_promotions.feature @@ -17,7 +17,7 @@ Feature: Seeing order with different promotions And there is a customer "lucy@teamlucifer.com" that placed an order "#00000666" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing prices and discount prices of order item Given the customer bought 2 "PHP T-Shirt" products And the customer bought a single "Symfony Mug" diff --git a/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature b/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature index 3d87782ae6..cfea540d13 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_with_items.feature @@ -15,7 +15,7 @@ Feature: Seeing an order with its items And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing order items When I view the summary of the order "#00000666" Then it should have 2 items diff --git a/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature b/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature index a6c1513e8f..ababb1317c 100644 --- a/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature +++ b/features/admin/order/managing_orders/order_details/seeing_order_without_shipping_address.feature @@ -16,7 +16,7 @@ Feature: Seeing an order without shipping address And the customer chose "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing basic information about an order When I view the summary of the order "#00000666" Then it should have been placed by the customer "lucy@teamlucifer.com" diff --git a/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature b/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature index eab25f8a0e..82bae88b86 100644 --- a/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature +++ b/features/admin/order/managing_orders/order_details/seeing_province_created_manually_on_order_page.feature @@ -19,7 +19,7 @@ Feature: Seeing province created manually on order summary page And the customer chose "DHL" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing manually definied province on order summary page When I view the summary of the order "#00000666" Then I should see "East of England" as province in the shipping address diff --git a/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature b/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature index 104606918e..f13811169c 100644 --- a/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature +++ b/features/admin/order/managing_orders/order_details/seeing_shipment_shipping_date.feature @@ -15,7 +15,7 @@ Feature: Seeing shipment shipping date And it is "20-02-2020 10:30:05" now And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing shipped at date When I view the summary of the order "#00000777" And I ship this order diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature index 8e38ba6a20..4c6504be43 100644 --- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature +++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_channel.feature @@ -13,7 +13,7 @@ Feature: Filtering orders by a channel And this customer has also placed an order "#00000003" on a channel "Web-US" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering orders by a chosen channel When I browse orders And I choose "Web-EU" as a channel filter @@ -23,7 +23,7 @@ Feature: Filtering orders by a channel And I should see an order with "#00000002" number But I should not see an order with "#00000003" number - @ui @api + @todo @ui @api Scenario: Filtering orders by an another channel When I browse orders And I choose "Web-US" as a channel filter diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature index e6b39dd5ab..97429d84b3 100644 --- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature +++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_date.feature @@ -12,7 +12,7 @@ Feature: Filtering orders And this customer has also placed an order "#00000003" at "2016-12-06 10:00" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering orders by date from When I browse orders And I specify filter date from as "2016-12-05 08:30" @@ -22,7 +22,7 @@ Feature: Filtering orders And I should see an order with "#00000003" number But I should not see an order with "#00000001" number - @ui @api + @todo @ui @api Scenario: Filtering orders by date to When I browse orders And I specify filter date to as "2016-12-05 09:30" @@ -32,7 +32,7 @@ Feature: Filtering orders And I should see an order with "#00000002" number But I should not see an order with "#00000003" number - @ui @api + @todo @ui @api Scenario: Filtering orders by date from to When I browse orders And I specify filter date from as "2016-12-05 08:30" @@ -43,7 +43,7 @@ Feature: Filtering orders But I should not see an order with "#00000001" number And I should not see an order with "#00000003" number - @ui @api + @todo @ui @api Scenario: Filtering orders by date from without time When I browse orders And I specify filter date from as "2016-12-05" @@ -54,7 +54,7 @@ Feature: Filtering orders And I should see an order with "#00000003" number But I should not see an order with "#00000001" number - @ui @api + @todo @ui @api Scenario: Filtering orders placed at midnight or just before midnight Given this customer has placed an order "#00000004" at "2016-12-10 00:00" And this customer has also placed an order "#00000005" at "2016-12-11 23:59" diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature index f998fdf220..646e2ece75 100644 --- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature +++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_products.feature @@ -17,7 +17,7 @@ Feature: Filtering orders by products And the customer chose "Free" shipping method to "United States" with "Offline" payment And I am logged in as an administrator - @ui @api @javascript + @todo @ui @api @javascript Scenario: Filtering orders by product When I browse orders And I filter by product "Galaxy T-Shirt" @@ -25,7 +25,7 @@ Feature: Filtering orders by products And I should see an order with "#0000001" number And I should see an order with "#0000003" number - @ui @api @mink:chromedriver + @todo @ui @api @mink:chromedriver Scenario: Filtering orders by multiple products When I browse orders And I filter by products "Galaxy T-Shirt" and "Space Dress" diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature index 23ea147262..9f1d7e87b7 100644 --- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature +++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_shipping_method.feature @@ -23,7 +23,7 @@ Feature: Filtering orders by a shipping method And the customer chose "DHL" shipping method to "United States" with "Offline" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering orders by DHL shipping method When I browse orders And I choose "DHL" as a shipping method filter @@ -32,7 +32,7 @@ Feature: Filtering orders by a shipping method And I should see an order with "#000001338" number And I should not see an order with "#000001337" number - @ui @api + @todo @ui @api Scenario: Filtering orders by an another shipping method When I browse orders And I choose "Free" as a shipping method filter diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature index 4fa36f9b1f..aba465fc3b 100644 --- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature +++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_total_in_different_currencies.feature @@ -18,14 +18,14 @@ Feature: Filtering orders by total in different currencies And I am logged in as an administrator And I am browsing orders - @ui @api + @todo @ui @api Scenario: Filtering orders by currency alone When I choose "British Pound" as the filter currency And I filter Then I should see 3 orders in the list But I should not see any orders with currency "USD" - @ui @api + @todo @ui @api Scenario: Filtering orders with total greater than specified amount When I choose "US Dollar" as the filter currency And I specify filter total being greater than 100 @@ -36,7 +36,7 @@ Feature: Filtering orders by total in different currencies But I should not see an order with "#00000001" number And I should not see any orders with currency "GBP" - @ui @api + @todo @ui @api Scenario: Filtering orders with total less than specified amount When I choose "US Dollar" as the filter currency And I specify filter total being less than 200 @@ -47,7 +47,7 @@ Feature: Filtering orders by total in different currencies But I should not see an order with "#00000002" number And I should not see any orders with currency "GBP" - @ui @api + @todo @ui @api Scenario: Filtering order with total from a specified range When I choose "British Pound" as the filter currency And I specify filter total being greater than 150.50 @@ -59,7 +59,7 @@ Feature: Filtering orders by total in different currencies And I should not see an order with "#00000006" number And I should not see any orders with currency "USD" - @ui @api + @todo @ui @api Scenario: Filtering orders by total in given range but with no currency provided When I specify filter total being greater than 150 And I specify filter total being less than 200 diff --git a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature index 007a7cdb3f..644091e2be 100644 --- a/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature +++ b/features/admin/order/managing_orders/order_filtration/filtering_orders_by_variants.feature @@ -26,7 +26,7 @@ Feature: Filtering orders by variants And the customer chose "Free" shipping method to "United States" with "Offline" payment And I am logged in as an administrator - @ui @api @javascript + @todo @ui @api @javascript Scenario: Filtering orders by variant When I browse orders And I filter by variant "Sundress" @@ -34,7 +34,7 @@ Feature: Filtering orders by variants And I should see an order with "#0000002" number And I should see an order with "#0000003" number - @ui @api @mink:chromedriver + @todo @ui @api @mink:chromedriver Scenario: Filtering orders by multiple variants of the same product When I browse orders And I filter by variants "Nebula Top" and "Neutron Sleeveless" @@ -42,7 +42,7 @@ Feature: Filtering orders by variants And I should see an order with "#0000001" number And I should see an order with "#0000002" number - @ui @api @javascript + @todo @ui @api @javascript Scenario: Filtering orders by multiple variants of different products When I browse orders And I filter by variants "Neutron Sleeveless" and "Sundress" diff --git a/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature b/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature index defce54801..25ca0e5499 100644 --- a/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature +++ b/features/admin/payment/managing_payment_methods/being_redirected_to_previous_filtered_page.feature @@ -11,7 +11,7 @@ Feature: Being redirected to previous filtered page And this payment method has been disabled And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Being redirected to previous filtered page after cancelling creating a new payment method When I browse payment methods And I choose enabled filter diff --git a/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature b/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature index 37288549b4..af19f7671e 100644 --- a/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature +++ b/features/admin/payment/managing_payment_methods/browsing_payment_methods.feature @@ -7,10 +7,10 @@ Feature: Browsing payment methods Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing defined payment methods Given the store has a payment method "Offline" with a code "OFF" - And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and Paypal Express Checkout gateway + And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and "Paypal Express Checkout" gateway When I browse payment methods Then I should see 2 payment methods in the list And the payment method "PayPal Express Checkout" should be in the registry diff --git a/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature b/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature index 1dd7d0c9de..182ce5ccf9 100644 --- a/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature +++ b/features/admin/payment/managing_payment_methods/deleting_multiple_payment_methods.feature @@ -7,10 +7,10 @@ Feature: Deleting multiple payment methods Background: Given the store has a payment method "Offline" with a code "Offline" And the store has also a payment method "Bank transfer" with a code "transfer" - And the store has also a payment method "PayPal Express Checkout" with a code "paypal" and Paypal Express Checkout gateway + And the store has also a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple payment methods at once When I browse payment methods And I check the "Offline" payment method diff --git a/features/admin/payment/managing_payment_methods/deleting_payment_method.feature b/features/admin/payment/managing_payment_methods/deleting_payment_method.feature index 3aafd8fe79..f5daea0d3a 100644 --- a/features/admin/payment/managing_payment_methods/deleting_payment_method.feature +++ b/features/admin/payment/managing_payment_methods/deleting_payment_method.feature @@ -8,7 +8,7 @@ Feature: Deleting payment methods Given the store has a payment method "Offline" with a code "Offline" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted payment method should disappear from the registry When I delete the "Offline" payment method Then I should be notified that it has been successfully deleted diff --git a/features/admin/payment/managing_payment_methods/editing_payment_method.feature b/features/admin/payment/managing_payment_methods/editing_payment_method.feature index d3ca12fa2d..55cd21b3b6 100644 --- a/features/admin/payment/managing_payment_methods/editing_payment_method.feature +++ b/features/admin/payment/managing_payment_methods/editing_payment_method.feature @@ -15,7 +15,7 @@ Feature: Editing payment methods And I rename it to "Cash on delivery" in "English (United States)" And I save my changes Then I should be notified that it has been successfully edited - And this payment method name should be "Cash on delivery" + And this payment method "Name" should be "Cash on delivery" @ui @api Scenario: Disabling payment method diff --git a/features/admin/payment/managing_payment_methods/editing_payment_method_with_paypal_express_checkout_gateway.feature b/features/admin/payment/managing_payment_methods/editing_payment_method_with_paypal_express_checkout_gateway.feature new file mode 100644 index 0000000000..033f4db2fe --- /dev/null +++ b/features/admin/payment/managing_payment_methods/editing_payment_method_with_paypal_express_checkout_gateway.feature @@ -0,0 +1,54 @@ +@managing_payment_methods +Feature: Editing payment method configured with a PayPal Express Checkout gateway + In order to change configuration of a payment method + As an Administrator + I want to be able to edit payment method with a PayPal Express Checkout gateway + + Background: + Given the store operates on a single channel in "United States" + And the store has a payment method "PayPal Express Checkout" with a code "paypal" and "Paypal Express Checkout" gateway + And I am logged in as an administrator + + @ui @no-api + Scenario: Changing gateway username + When I want to modify the "PayPal Express Checkout" payment method + And I update its "Username" with "new_username" + And I save my changes + Then I should be notified that it has been successfully edited + And its gateway configuration "Username" should be "new_username" + + @ui @no-api + Scenario: Changing gateway password + When I want to modify the "PayPal Express Checkout" payment method + And I update its "Password" with "new_password" + And I save my changes + Then I should be notified that it has been successfully edited + And its gateway configuration "Password" should be "new_password" + + @ui @no-api + Scenario: Changing gateway signature + When I want to modify the "PayPal Express Checkout" payment method + And I update its "Signature" with "new_signature" + And I save my changes + Then I should be notified that it has been successfully edited + And its gateway configuration "Signature" should be "new_signature" + + @ui @no-api + Scenario: Changing gateway sandbox mode + When I want to modify the "PayPal Express Checkout" payment method + And I enable sandbox mode + And I save my changes + Then I should be notified that it has been successfully edited + And this payment method should be in sandbox mode + + @api @ui + Scenario: Changing whole gateway configuration + When I want to modify the "PayPal Express Checkout" payment method + And I set its "Username" as "new_username", "Password" as "new_password" and "Signature" as "new_signature" + And I enable sandbox mode + And I save my changes + Then I should be notified that it has been successfully edited + And its gateway configuration "Username" should be "new_username" + And its gateway configuration "Password" should be "new_password" + And its gateway configuration "Signature" should be "new_signature" + And this payment method should be in sandbox mode diff --git a/features/admin/payment/managing_payment_methods/editing_payment_method_with_stripe_checkout_gateway.feature b/features/admin/payment/managing_payment_methods/editing_payment_method_with_stripe_checkout_gateway.feature new file mode 100644 index 0000000000..331eccb42f --- /dev/null +++ b/features/admin/payment/managing_payment_methods/editing_payment_method_with_stripe_checkout_gateway.feature @@ -0,0 +1,35 @@ +@managing_payment_methods +Feature: Editing payment method configured with a Stripe Checkout gateway + In order to change which payment methods are available in my store + As an Administrator + I want to be able to edit payment method + + Background: + Given the store operates on a single channel in "United States" + And the store has a payment method "Stripe Checkout" with a code "stripe" and "Stripe Checkout" gateway + And I am logged in as an administrator + + @ui @no-api + Scenario: Changing Stripe Checkout gateway publishable key + When I want to modify the "Stripe Checkout" payment method + And I update its "Publishable key" with "some_publishable_key" + And I save my changes + Then I should be notified that it has been successfully edited + And this payment method "Publishable key" should be "some_publishable_key" + + @ui @no-api + Scenario: Changing Stripe Checkout gateway secret key + When I want to modify the "Stripe Checkout" payment method + And I update its "Secret key" with "some_secret_key" + And I save my changes + Then I should be notified that it has been successfully edited + And this payment method "Secret key" should be "some_secret_key" + + @api @ui + Scenario: Changing whole gateway configuration + When I want to modify the "Stripe Checkout" payment method + And I set its "Publishable key" as "new_publishable_key" and "Secret key" as "new_secret_key" + And I save my changes + Then I should be notified that it has been successfully edited + And its gateway configuration "Publishable key" should be "new_publishable_key" + And its gateway configuration "Secret key" should be "new_secret_key" diff --git a/features/admin/payment/managing_payment_methods/payment_method_validation.feature b/features/admin/payment/managing_payment_methods/payment_method_validation.feature index 8495bd5fa1..4f818904c5 100644 --- a/features/admin/payment/managing_payment_methods/payment_method_validation.feature +++ b/features/admin/payment/managing_payment_methods/payment_method_validation.feature @@ -78,9 +78,9 @@ Feature: Payment method validation When I want to create a new payment method with "Stripe Checkout" gateway factory And I name it "Stripe Checkout" in "English (United States)" And I specify its code as "SC" - And I configure it with only "publishable key" + And I configure it with only "Publishable key" And I add it - Then I should be notified that I have to specify stripe "secret key" + Then I should be notified that I have to specify stripe "Secret key" And the payment method with code "PEC" should not be added @ui @api @@ -88,9 +88,9 @@ Feature: Payment method validation When I want to create a new payment method with "Stripe Checkout" gateway factory And I name it "Stripe Checkout" in "English (United States)" And I specify its code as "SC" - And I configure it with only "secret key" + And I configure it with only "Secret key" And I add it - Then I should be notified that I have to specify stripe "publishable key" + Then I should be notified that I have to specify stripe "Publishable key" And the payment method with code "PEC" should not be added @no-ui @api diff --git a/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature b/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature index f847f46a28..8752424ad1 100644 --- a/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature +++ b/features/admin/payment/managing_payment_methods/preventing_deletion_of_used_payment_method.feature @@ -14,7 +14,7 @@ Feature: Prevent deletion of used payment method And the customer chose "DHL Express" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Being unable to delete a payment method which is in use When I try to delete the "Cash on Delivery" payment method Then I should be notified that it is in use diff --git a/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature b/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature index b30c79cad3..2b00133ab9 100644 --- a/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature +++ b/features/admin/payment/managing_payment_methods/sorting_payment_methods.feature @@ -7,7 +7,7 @@ Feature: Sorting listed payment methods Background: Given the store operates on a single channel in "United States" And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales - And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and Paypal Express Checkout gateway + And the store has a payment method "PayPal Express Checkout" with a code "PAYPAL" and "Paypal Express Checkout" gateway And this payment method is named "Ekspresowy Paypal" in the "Polish (Poland)" locale And the store has a payment method "Offline" with a code "Offline" And this payment method is named "Płatność Offline" in the "Polish (Poland)" locale @@ -15,14 +15,14 @@ Feature: Sorting listed payment methods And this payment method is named "Płatność Przy Odbiorze" in the "Polish (Poland)" locale And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Payment methods can be sorted by their codes Given I am browsing payment methods When I start sorting payment methods by code Then I should see 3 payment methods in the list And the first payment method on the list should have code "cash_on_delivery" - @ui @api + @todo @ui @api Scenario: Changing the order of sorting payment methods by their codes Given I am browsing payment methods And the payment methods are already sorted by code @@ -30,14 +30,14 @@ Feature: Sorting listed payment methods Then I should see 3 payment methods in the list And the first payment method on the list should have code "PAYPAL" - @ui @api + @todo @ui @api Scenario: Payment methods can be sorted by their names Given I am browsing payment methods When I start sorting payment methods by name Then I should see 3 payment methods in the list And the first payment method on the list should have name "Cash on Delivery" - @ui @api + @todo @ui @api Scenario: Changing the order of sorting payment methods by their names Given I am browsing payment methods And the payment methods are already sorted by name @@ -45,7 +45,7 @@ Feature: Sorting listed payment methods Then I should see 3 payment methods in the list And the first payment method on the list should have name "PayPal Express Checkout" - @ui @api + @todo @ui @api Scenario: Payment methods are always sorted in the default locale Given I change my locale to "Polish (Poland)" And I am browsing payment methods diff --git a/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature b/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature index f4778dfe95..b95f120aef 100644 --- a/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature +++ b/features/admin/payment/managing_payment_methods/sorting_payment_methods_by_position.feature @@ -11,20 +11,20 @@ Feature: Sorting listed payment methods by position And the store allows paying with "Offline" at position 1 And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Payment methods are sorted by position in ascending order by default When I browse payment methods Then I should see 3 payment methods in the list And the first payment method on the list should have name "Paypal Express Checkout" And the last payment method on the list should have name "Cash on Delivery" - @ui @api + @todo @ui @api Scenario: Payment method added at no position is added as the last one Given the store allows paying with "Credit Card" When I browse payment methods Then the last payment method on the list should have name "Credit Card" - @ui @api + @todo @ui @api Scenario: Payment method added at position 0 is added as the first one Given the store also allows paying with "Credit Card" at position 0 When I browse payment methods diff --git a/features/admin/payment/managing_payments/browsing_payments.feature b/features/admin/payment/managing_payments/browsing_payments.feature index b809cf1ef8..04588a9a1c 100644 --- a/features/admin/payment/managing_payments/browsing_payments.feature +++ b/features/admin/payment/managing_payments/browsing_payments.feature @@ -1,6 +1,6 @@ @managing_payments Feature: Browsing payments - In order to manage all payments regardlessly of orders + In order to manage all payments regardless of orders As an Administrator I want to browse all payments in the system diff --git a/features/admin/payment/managing_payments/sorting_payments.feature b/features/admin/payment/managing_payments/sorting_payments.feature new file mode 100644 index 0000000000..8fc448276f --- /dev/null +++ b/features/admin/payment/managing_payments/sorting_payments.feature @@ -0,0 +1,28 @@ +@managing_payments +Feature: Sorting payments + In order to manage all payments regardless of orders + As an Administrator + I want to sort payments by date + + Background: + Given the store operates on a single channel in "United States" + And the store ships everywhere for Free + And the store has a product "Apple" + And the store allows paying with "Cash on Delivery" + And there is an "#00000001" order with "Apple" product + And there is an "#00000002" order with "Apple" product ordered later + And I am logged in as an administrator + + @ui @api-todo + Scenario: Sorting payments by date in ascending order + When I browse payments + And I sort payments by date in ascending order + Then I should see payment for the "#00000001" order as 1st in the list + And I should see payment for the "#00000002" order as 2nd in the list + + @ui @api-todo + Scenario: Sorting payments by date in descending order again + When I browse payments + And I sort payments by date in descending order + Then I should see payment for the "#00000002" order as 1st in the list + And I should see payment for the "#00000001" order as 2nd in the list diff --git a/features/admin/placing_order_as_impersonated_customers.feature b/features/admin/placing_order_as_impersonated_customers.feature index de0a14520e..51f0b91e99 100644 --- a/features/admin/placing_order_as_impersonated_customers.feature +++ b/features/admin/placing_order_as_impersonated_customers.feature @@ -13,7 +13,7 @@ Feature: Placing an order as impersonated shop users And there is a customer "Tanith Low" identified by an email "tanith.low@london.uk" and a password "tanithlow" And I am logged in as an administrator - @ui + @todo @ui Scenario: Placing an order as an impersonated shop user When I view details of the customer "tanith.low@london.uk" And I impersonate them @@ -24,7 +24,7 @@ Feature: Placing an order as impersonated shop users And I browse orders of a customer "tanith.low@london.uk" Then I should see a single order in the list - @ui + @todo @ui Scenario: Placing an order as an impersonated shop user when the shop user was already logged When I sign in with email "john.doe@london.uk" and password "johndoe" And I view details of the customer "tanith.low@london.uk" diff --git a/features/admin/product/managing_product_association_types/browsing_product_association_types.feature b/features/admin/product/managing_product_association_types/browsing_product_association_types.feature index 181f1288e5..361a65f91f 100644 --- a/features/admin/product/managing_product_association_types/browsing_product_association_types.feature +++ b/features/admin/product/managing_product_association_types/browsing_product_association_types.feature @@ -9,7 +9,7 @@ Feature: Browsing product association types And the store has also a product association type "Up sell" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing product association types in the store When I want to browse product association types Then I should see 2 product association types in the list diff --git a/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature b/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature index 52e7d75c54..1352c7caef 100644 --- a/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature +++ b/features/admin/product/managing_product_association_types/deleting_multiple_product_association_types.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple product association types And the store has also a product association type "Accessories" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple product association types at once When I browse product association types And I check the "Cross sell" product association type diff --git a/features/admin/product/managing_product_association_types/filtering_product_association_types.feature b/features/admin/product/managing_product_association_types/filtering_product_association_types.feature index 0c4b3a727b..188047a896 100644 --- a/features/admin/product/managing_product_association_types/filtering_product_association_types.feature +++ b/features/admin/product/managing_product_association_types/filtering_product_association_types.feature @@ -9,14 +9,14 @@ Feature: Filtering product association types And the store has also a product association type "Up sell" with a code "up_sell" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering product association types by name When I want to browse product association types And I filter product association types with name containing "Up" Then I should see only one product association type in the list And I should see the product association type "Up sell" in the list - @ui @api + @todo @ui @api Scenario: Filtering product association types by code When I want to browse product association types And I filter product association types with code containing "cross" diff --git a/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature index effe7330a6..8ae0b23e61 100644 --- a/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_checkbox_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new checkbox product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new checkbox product attribute When I want to create a new checkbox product attribute And I specify its code as "t_shirt_with_cotton" @@ -17,7 +17,7 @@ Feature: Adding a new checkbox product attribute Then I should be notified that it has been successfully created And the checkbox attribute "T-Shirt with cotton" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding a checkbox product attribute When I want to create a new checkbox product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature index 570cfaa36a..76ae2eed90 100644 --- a/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_float_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new float product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new float product attribute When I want to create a new float product attribute And I specify its code as "display_size" @@ -17,7 +17,7 @@ Feature: Adding a new float product attribute Then I should be notified that it has been successfully created And the float attribute "Display Size" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding a float product attribute When I want to create a new float product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature index 8a51d121d1..8ce0080d57 100644 --- a/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_integer_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new integer product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new integer product attribute When I want to create a new integer product attribute And I specify its code as "book_pages" @@ -17,7 +17,7 @@ Feature: Adding a new integer product attribute Then I should be notified that it has been successfully created And the integer attribute "Book pages" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding a integer product attribute When I want to create a new integer product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature b/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature index 897e8fe7eb..e77362d4e4 100644 --- a/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_non_translatable_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new non-translatable product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new non-translatable product attribute When I want to create a new integer product attribute And I specify its code as "damage" diff --git a/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature index 8b4a7b8766..9825959ed1 100644 --- a/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_percent_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new percent product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new percent product attribute When I want to create a new percent product attribute And I specify its code as "t_shirt_cotton_content" @@ -17,7 +17,7 @@ Feature: Adding a new percent product attribute Then I should be notified that it has been successfully created And the percent attribute "T-Shirt cotton content" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding a percent product attribute When I want to create a new percent product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature index d50fb2471a..4d2c6ad413 100644 --- a/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_select_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new select product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @javascript @api + @todo @ui @javascript @api Scenario: Adding a new select product attribute When I want to create a new select product attribute And I specify its code as "mug_material" @@ -18,7 +18,7 @@ Feature: Adding a new select product attribute Then I should be notified that it has been successfully created And the select attribute "Mug material" should appear in the store - @ui @javascript @api + @todo @ui @javascript @api Scenario: Adding multiple select product attribute When I want to create a new select product attribute And I specify its code as "mug_material" @@ -30,7 +30,7 @@ Feature: Adding a new select product attribute Then I should be notified that it has been successfully created And the select attribute "Mug material" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding a select product attribute When I want to create a new select product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature index 41852229db..8ea4cdf240 100644 --- a/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_text_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new text product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new text product attribute When I want to create a new text product attribute And I specify its code as "t_shirt_brand" @@ -17,7 +17,7 @@ Feature: Adding a new text product attribute Then I should be notified that it has been successfully created And the text attribute "T-Shirt brand" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding text a product attribute When I want to create a new text product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature b/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature index b8934594bf..46f7439113 100644 --- a/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/adding_textarea_product_attribute.feature @@ -8,7 +8,7 @@ Feature: Adding a new textarea product attribute Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new textarea product attribute When I want to create a new textarea product attribute And I specify its code as "t_shirt_details" @@ -17,7 +17,7 @@ Feature: Adding a new textarea product attribute Then I should be notified that it has been successfully created And the textarea attribute "T-Shirt details" should appear in the store - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled type field while adding a textarea product attribute When I want to create a new textarea product attribute Then the type field should be disabled diff --git a/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature b/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature index 0d30a90736..2bd306a2ac 100644 --- a/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature +++ b/features/admin/product/managing_product_attributes/browsing_all_product_attributes.feature @@ -10,7 +10,7 @@ Feature: Browsing product attributes And the store has a integer product attribute "Book pages" with code "book_pages" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing all product attributes in store When I want to see all product attributes in store Then I should see 3 product attributes in the list diff --git a/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature b/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature index 43137fc4a3..e1d86e950f 100644 --- a/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature +++ b/features/admin/product/managing_product_attributes/deleting_multiple_product_attributes.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple product attributes And the store has a integer product attribute "Pages" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple product attributes at once When I browse product attributes And I check the "Publisher" product attribute diff --git a/features/admin/product/managing_product_attributes/deleting_product_attribute.feature b/features/admin/product/managing_product_attributes/deleting_product_attribute.feature index a099670a31..df10f240c3 100644 --- a/features/admin/product/managing_product_attributes/deleting_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/deleting_product_attribute.feature @@ -8,13 +8,13 @@ Feature: Deleting a product attribute Given I am logged in as an administrator And the store has a product "44 Magnum" - @ui @api + @todo @ui @api Scenario: Trying to delete an attribute from the registry when a product uses it Given this product has a text attribute "Gun caliber" with value "11 mm" When I delete this product attribute Then I should be notified that it is in use - @ui @api + @todo @ui @api Scenario: Deleting a text product attribute when it's not used Given the store has a text product attribute "Gun caliber" When I delete this product attribute diff --git a/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature b/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature index 80c86be83a..b7ab31d5cc 100644 --- a/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/editing_select_product_attribute.feature @@ -9,7 +9,7 @@ Feature: Editing a select product attribute And the store has a select product attribute "T-Shirt material" with value "Banana skin" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Editing a select product attribute name When I want to edit this product attribute And I change its name to "T-Shirt material" in "English (United States)" @@ -17,7 +17,7 @@ Feature: Editing a select product attribute Then I should be notified that it has been successfully edited And the select attribute "T-Shirt material" should appear in the store - @ui @api + @todo @ui @api Scenario: Editing a select product attribute value When I want to edit this product attribute And I change its value "Banana skin" to "Orange skin" @@ -25,7 +25,7 @@ Feature: Editing a select product attribute Then I should be notified that it has been successfully edited And this product attribute should have value "Orange skin" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Adding a new value to an existing select product attribute When I want to edit this product attribute And I add value "Orange skin" in "English (United States)" @@ -33,7 +33,7 @@ Feature: Editing a select product attribute Then I should be notified that it has been successfully edited And this product attribute should have value "Orange skin" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Deleting a value from an existing select product attribute When I want to edit this product attribute And I delete value "Banana skin" @@ -41,12 +41,12 @@ Feature: Editing a select product attribute Then I should be notified that it has been successfully edited And this product attribute should not have value "Banana skin" - @ui @api + @todo @ui @api Scenario: Being unable to change code of an existing product attribute When I want to edit this product attribute Then I should not be able to edit its code - @ui @api + @todo @ui @api Scenario: Being unable to change type of an existing product attribute When I want to edit this product attribute Then I should not be able to edit its type diff --git a/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature b/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature index 94403887b7..d8318f89c9 100644 --- a/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature +++ b/features/admin/product/managing_product_attributes/editing_text_product_attribute.feature @@ -9,7 +9,7 @@ Feature: Editing a text product attribute And the store has a text product attribute "T-Shirt cotton brand" with code "t_shirt_brand" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Editing product attribute name When I want to edit this product attribute And I change its name to "T-Shirt material" in "English (United States)" @@ -17,12 +17,12 @@ Feature: Editing a text product attribute Then I should be notified that it has been successfully edited And the text attribute "T-Shirt material" should appear in the store - @ui @api + @todo @ui @api Scenario: Being unable to change code of an existing product attribute When I want to edit this product attribute Then I should not be able to edit its code - @ui @api + @todo @ui @api Scenario: Being unable to change type of an existing product attribute When I want to edit this product attribute Then I should not be able to edit its type diff --git a/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature b/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature index dab34888e7..968603dace 100644 --- a/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature +++ b/features/admin/product/managing_product_attributes/product_attribute_unique_code_validation.feature @@ -8,7 +8,7 @@ Feature: Product attribute unique code validation Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new product attribute with taken code Given the store has a text product attribute "T-Shirt cotton material" with code "t_shirt_material" When I want to create a new text product attribute diff --git a/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature b/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature index 9362431da5..08e6eb330a 100644 --- a/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature +++ b/features/admin/product/managing_product_attributes/seeing_correct_select_attribute_values_in_different_locale_than_default_one.feature @@ -8,7 +8,7 @@ Feature: Seeing correct select attribute values in different locale than default Given the store is available in "French (France)" And I am logged in as an administrator - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Seeing correct attribute values in different locale than default one When I want to create a new select product attribute And I specify its code as "mug_material" diff --git a/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature b/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature index eed542b5eb..eedc1f6d90 100644 --- a/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature +++ b/features/admin/product/managing_product_attributes/select_product_attribute_validation.feature @@ -8,7 +8,7 @@ Feature: Select product attribute validation Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Trying to add a new select product attribute with wrong max entries value When I want to create a new select product attribute And I name it "Mug material" in "English (United States)" @@ -22,7 +22,7 @@ Feature: Select product attribute validation Then I should be notified that max entries value must be greater or equal to the min entries value And the attribute with code "mug_material" should not appear in the store - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Trying to add a new select product attribute with wrong min entries value When I want to create a new select product attribute And I name it "Mug material" in "English (United States)" @@ -36,7 +36,7 @@ Feature: Select product attribute validation Then I should be notified that min entries value must be lower or equal to the number of added choices And the attribute with code "mug_material" should not appear in the store - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Trying to add a new select product attribute with specified entries values but without multiple option When I want to create a new select product attribute And I name it "Mug material" in "English (United States)" diff --git a/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature b/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature index e4a77d1bb6..e3a5f55692 100644 --- a/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature +++ b/features/admin/product/managing_product_attributes/sorting_product_attributes_by_position.feature @@ -10,21 +10,21 @@ Feature: Sorting listed product attributes by position And the store has a integer product attribute "Book pages" at position 0 And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Product attributes are sorted by position in ascending order by default When I want to see all product attributes in store Then I should see 3 product attributes in the list And the first product attribute on the list should have name "Book pages" And the last product attribute on the list should have name "T-Shirt with cotton" - @ui @api + @todo @ui @api Scenario: Product attribute added at no position gets put at the bottom of the list Given the store has also a text product attribute "Drive type" When I want to see all product attributes in store Then I should see 4 product attributes in the list And the last product attribute on the list should have name "Drive type" - @ui @api + @todo @ui @api Scenario: Product attribute added at position 0 is added as the first one Given the store has also a text product attribute "Drive type" at position 0 When I want to see all product attributes in store diff --git a/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature b/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature index 6f51b660c1..30ef5fef0c 100644 --- a/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature +++ b/features/admin/product/managing_product_attributes/text_product_attribute_validation.feature @@ -16,7 +16,7 @@ Feature: Text product attribute validation And I save my changes Then I should be notified that the locale is not available - @ui @api + @todo @ui @api Scenario: Trying to add a new text product attribute without name When I want to create a new text product attribute And I specify its code as "t_shirt_with_cotton" @@ -25,7 +25,7 @@ Feature: Text product attribute validation Then I should be notified that name is required And the attribute with code "t_shirt_with_cotton" should not appear in the store - @ui @api + @todo @ui @api Scenario: Trying to add a new text product attribute without code When I want to create a new text product attribute And I name it "T-Shirt brand" in "English (United States)" @@ -34,7 +34,7 @@ Feature: Text product attribute validation Then I should be notified that code is required And the attribute with name "T-Shirt brand" should not appear in the store - @ui @api + @todo @ui @api Scenario: Trying to remove name for existing text product attribute Given the store has a text product attribute "T-Shirt cotton brand" When I want to edit this product attribute @@ -43,7 +43,7 @@ Feature: Text product attribute validation Then I should be notified that name is required And the text attribute "T-Shirt cotton brand" should still be in the store - @ui @api + @todo @ui @api Scenario: Trying to add a new text product attribute with wrong configuration When I want to create a new text product attribute And I name it "T-Shirt brand" in "English (United States)" diff --git a/features/admin/product/managing_product_options/adding_product_option.feature b/features/admin/product/managing_product_options/adding_product_option.feature index 9d120344d2..2872b809be 100644 --- a/features/admin/product/managing_product_options/adding_product_option.feature +++ b/features/admin/product/managing_product_options/adding_product_option.feature @@ -8,7 +8,7 @@ Feature: Adding a new product option Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Adding a new product option with two required option values When I want to create a new product option And I name it "T-Shirt size" in "English (United States)" @@ -21,7 +21,7 @@ Feature: Adding a new product option And product option "T-Shirt size" should have the "S" option value And product option "T-Shirt size" should have the "M" option value - @ui @api + @todo @ui @api Scenario: Adding a new product option without any option values When I want to create a new product option And I name it "T-Shirt size" in "English (United States)" @@ -31,7 +31,7 @@ Feature: Adding a new product option Then I should be notified that it has been successfully created And the product option "T-Shirt size" should appear in the registry - @ui @javascript @api + @todo @ui @javascript @api Scenario: Adding a new product option with one option value When I want to create a new product option And I name it "T-Shirt size" in "English (United States)" diff --git a/features/admin/product/managing_product_options/browsing_product_options.feature b/features/admin/product/managing_product_options/browsing_product_options.feature index b2f3638077..66c976df61 100644 --- a/features/admin/product/managing_product_options/browsing_product_options.feature +++ b/features/admin/product/managing_product_options/browsing_product_options.feature @@ -4,7 +4,7 @@ Feature: Browsing product options As an Administrator I want to be able to browse product options - @ui @api + @todo @ui @api Scenario: Browsing defined product options Given I am logged in as an administrator And the store has a product option "T-Shirt size" with a code "t_shirt_size" diff --git a/features/admin/product/managing_product_options/deleting_multiple_product_options.feature b/features/admin/product/managing_product_options/deleting_multiple_product_options.feature index 269f1480f9..b325132107 100644 --- a/features/admin/product/managing_product_options/deleting_multiple_product_options.feature +++ b/features/admin/product/managing_product_options/deleting_multiple_product_options.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple product options And the store has also a product option "T-Shirt brand" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple product options at once When I browse product options And I check the "T-Shirt size" product option diff --git a/features/admin/product/managing_product_options/editing_product_option.feature b/features/admin/product/managing_product_options/editing_product_option.feature index b80356f7f8..b0b0dae34c 100644 --- a/features/admin/product/managing_product_options/editing_product_option.feature +++ b/features/admin/product/managing_product_options/editing_product_option.feature @@ -9,7 +9,7 @@ Feature: Editing product options And the store has a product option "T-Shirt size" with a code "t_shirt_size" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Renaming the product option Given this product option has the "S" option value with code "t_shirt_size_s" And this product option has also the "M" option value with code "t_shirt_size_m" @@ -19,7 +19,7 @@ Feature: Editing product options Then I should be notified that it has been successfully edited And this product option name should be "T-Shirt color" - @ui @api + @todo @ui @api Scenario: Not being able to edit code of an existing product option When I want to modify the "T-Shirt size" product option Then I should not be able to edit its code diff --git a/features/admin/product/managing_product_options/managing_values_of_product_option.feature b/features/admin/product/managing_product_options/managing_values_of_product_option.feature index 330fbc7b2c..ba16c453ca 100644 --- a/features/admin/product/managing_product_options/managing_values_of_product_option.feature +++ b/features/admin/product/managing_product_options/managing_values_of_product_option.feature @@ -11,7 +11,7 @@ Feature: Managing option values of a product option And this product option has also the "M" option value with code "OV2" And I am logged in as an administrator - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Adding an option value to an existing product option When I want to modify the "T-Shirt size" product option And I add the "L" option value identified by "OV3" @@ -19,7 +19,7 @@ Feature: Managing option values of a product option Then I should be notified that it has been successfully edited And this product option should have the "L" option value - @ui @javascript @todo + @todo @ui @javascript @todo Scenario: Removing an option value from an existing product option Given this product option has also the "L" option value with code "OV3" When I want to modify the "T-Shirt size" product option @@ -28,7 +28,7 @@ Feature: Managing option values of a product option Then I should be notified that it has been successfully edited And this product option should not have the "L" option value - @ui @javascript @todo + @todo @ui @javascript @todo Scenario: Removing and adding a new option value to an existing product option When I want to modify the "T-Shirt size" product option And I delete the "M" option value of this product option diff --git a/features/admin/product/managing_product_options/product_option_unique_code_validation.feature b/features/admin/product/managing_product_options/product_option_unique_code_validation.feature index adca682c77..84f935fcfe 100644 --- a/features/admin/product/managing_product_options/product_option_unique_code_validation.feature +++ b/features/admin/product/managing_product_options/product_option_unique_code_validation.feature @@ -9,7 +9,7 @@ Feature: Product option unique code validation And the store has a product option "T-Shirt size" with a code "t_shirt_size" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add product option with a taken code When I want to create a new product option And I name it "T-Shirt color" in "English (United States)" diff --git a/features/admin/product/managing_product_options/product_option_validation.feature b/features/admin/product/managing_product_options/product_option_validation.feature index 8ccf2ac9eb..464b091e61 100644 --- a/features/admin/product/managing_product_options/product_option_validation.feature +++ b/features/admin/product/managing_product_options/product_option_validation.feature @@ -9,7 +9,7 @@ Feature: Product option validation And the store has a product option "T-Shirt color" with a code "t_shirt_color" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new product option without specifying its code When I want to create a new product option And I name it "T-Shirt size" in "English (United States)" @@ -25,7 +25,7 @@ Feature: Product option validation And I try to save my changes Then I should be notified that the locale is not available - @ui @api + @todo @ui @api Scenario: Trying to add a new product option with a too long code When I want to create a new product option And I name it "T-Shirt size" in "English (United States)" @@ -33,7 +33,7 @@ Feature: Product option validation And I try to add it Then I should be notified that code is too long - @ui @api + @todo @ui @api Scenario: Trying to add a new product option without specifying its name When I want to create a new product option And I specify its code as "t_shirt_size" @@ -42,7 +42,7 @@ Feature: Product option validation Then I should be notified that name is required And the product option with code "t_shirt_size" should not be added - @ui @api + @todo @ui @api Scenario: Trying to remove name from an existing product option When I want to modify the "T-Shirt color" product option And I remove its name from "English (United States)" translation diff --git a/features/admin/product/managing_product_options/sorting_product_options_by_position.feature b/features/admin/product/managing_product_options/sorting_product_options_by_position.feature index bb1510261f..5ab25fcec4 100644 --- a/features/admin/product/managing_product_options/sorting_product_options_by_position.feature +++ b/features/admin/product/managing_product_options/sorting_product_options_by_position.feature @@ -10,20 +10,20 @@ Feature: Sorting listed product options by position And the store has also a product option "Mug type" at position 1 And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Product options are sorted by position in ascending order by default When I browse product options Then I should see 3 product options in the list And the first product option in the list should have name "Mug size" And the last product option in the list should have name "Mug color" - @ui @api + @todo @ui @api Scenario: Product option added at no position is added as the last one Given the store has a product option "Mug shape" When I browse product options Then the last product option in the list should have name "Mug shape" - @ui @api + @todo @ui @api Scenario: Product option added at position 0 is added as the first one Given the store has a product option "Mug shape" at position 0 When I browse product options diff --git a/features/admin/product/managing_product_reviews/accepting_product_review.feature b/features/admin/product/managing_product_reviews/accepting_product_review.feature index f6a3d9d3e5..245bb136c7 100644 --- a/features/admin/product/managing_product_reviews/accepting_product_review.feature +++ b/features/admin/product/managing_product_reviews/accepting_product_review.feature @@ -10,7 +10,7 @@ Feature: Accepting a product review And this product has a new review titled "Awesome" and rated 4 added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Accepting a product review When I want to browse product reviews And I accept the "Awesome" product review diff --git a/features/admin/product/managing_product_reviews/browsing_product_reviews.feature b/features/admin/product/managing_product_reviews/browsing_product_reviews.feature index 5d41ea19be..7e4040830a 100644 --- a/features/admin/product/managing_product_reviews/browsing_product_reviews.feature +++ b/features/admin/product/managing_product_reviews/browsing_product_reviews.feature @@ -11,7 +11,7 @@ Feature: Browsing product reviews And this product has also a review titled "Bad" and rated 1 with a comment "Really bad" added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing all product reviews in store When I want to browse product reviews Then I should see 2 reviews in the list diff --git a/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature b/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature index b6bd4d948f..2c8af09359 100644 --- a/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature +++ b/features/admin/product/managing_product_reviews/deleting_multiple_product_reviews.feature @@ -11,7 +11,7 @@ Feature: Deleting multiple product reviews And this product has also a review titled "Cool" and rated 4 with a comment "Quite cool" added by customer "aquaman@dc.com" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple product reviews at once When I browse product reviews And I check the "Awesome" product review diff --git a/features/admin/product/managing_product_reviews/deleting_product_review.feature b/features/admin/product/managing_product_reviews/deleting_product_review.feature index 9b90ea16fd..144536ea4a 100644 --- a/features/admin/product/managing_product_reviews/deleting_product_review.feature +++ b/features/admin/product/managing_product_reviews/deleting_product_review.feature @@ -10,7 +10,7 @@ Feature: Deleting product reviews And this product has a review titled "Awesome" and rated 5 with a comment "Nice product" added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleting a product review When I delete the "Awesome" product review Then I should be notified that it has been successfully deleted diff --git a/features/admin/product/managing_product_reviews/editing_product_review.feature b/features/admin/product/managing_product_reviews/editing_product_review.feature index e39aa6ed4b..9ffadde663 100644 --- a/features/admin/product/managing_product_reviews/editing_product_review.feature +++ b/features/admin/product/managing_product_reviews/editing_product_review.feature @@ -10,7 +10,7 @@ Feature: Editing product reviews And this product has a review titled "Awesome" and rated 4 with a comment "Nice product" added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Changing a title of a product review Given this product has a review titled "Bewilderig" and rated 5 with a comment "Nice product" added by customer "ross@teammike.com" When I want to modify the "Bewilderig" product review @@ -19,7 +19,7 @@ Feature: Editing product reviews Then I should be notified that it has been successfully edited And this product review title should be "Bewildering" - @ui @api + @todo @ui @api Scenario: Changing a comment of a product review Given this product has a review titled "Bewildering" and rated 5 with a comment "Nice prodct" added by customer "ross@teammike.com" When I want to modify the "Bewildering" product review @@ -28,7 +28,7 @@ Feature: Editing product reviews Then I should be notified that it has been successfully edited And this product review comment should be "Nice product" - @ui @api @javascript + @todo @ui @api @javascript Scenario: Changing a rating of a product review When I want to modify the "Awesome" product review And I choose 5 as its rating @@ -36,12 +36,12 @@ Feature: Editing product reviews Then I should be notified that it has been successfully edited And this product review rating should be 5 - @ui @no-api + @todo @ui @no-api Scenario: Seeing a product's name while editing a product review When I want to modify the "Awesome" product review Then I should be editing review of product "Lamborghini Gallardo Model" - @ui @no-api + @todo @ui @no-api Scenario: Seeing a customer's name while editing a product review When I want to modify the "Awesome" product review Then I should see the customer's name "Mike Ross" diff --git a/features/admin/product/managing_product_reviews/filtering_product_reviews.feature b/features/admin/product/managing_product_reviews/filtering_product_reviews.feature index 047dc30cdb..11cc8aa834 100644 --- a/features/admin/product/managing_product_reviews/filtering_product_reviews.feature +++ b/features/admin/product/managing_product_reviews/filtering_product_reviews.feature @@ -11,7 +11,7 @@ Feature: Browsing product reviews And this product has a new review titled "Bad" and rated 1 added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing accepted reviews When I want to browse product reviews And I choose "accepted" as a status filter diff --git a/features/admin/product/managing_product_reviews/product_review_validation.feature b/features/admin/product/managing_product_reviews/product_review_validation.feature index f94cc11dc7..0fdc24d7d5 100644 --- a/features/admin/product/managing_product_reviews/product_review_validation.feature +++ b/features/admin/product/managing_product_reviews/product_review_validation.feature @@ -10,7 +10,7 @@ Feature: Product review validation And this product has a review titled "Awesome" and rated 4 with a comment "Nice product" added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to remove title from an existing product review When I want to modify the "Awesome" product review And I remove its title @@ -18,7 +18,7 @@ Feature: Product review validation Then I should be notified that title is required And this product review should still be titled "Awesome" - @ui @api + @todo @ui @api Scenario: Trying to remove comment from an existing product review When I want to modify the "Awesome" product review And I remove its comment diff --git a/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature b/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature index d3564507ad..006e44d2cd 100644 --- a/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature +++ b/features/admin/product/managing_product_reviews/recalculating_product_average_rating.feature @@ -11,7 +11,7 @@ Feature: Recalculating product average rating And this product has a review titled "Not bad" and rated 3 with a comment "Not bad car" added by customer "specter@teamharvey.com" And I am logged in as an administrator - @ui @javascript @api + @todo @ui @javascript @api Scenario: Product's average rating is correctly recalculated after review's rate change When I want to modify the "Awesome" product review And I choose 5 as its rating @@ -19,7 +19,7 @@ Feature: Recalculating product average rating Then I should be notified that it has been successfully edited And average rating of product "Lamborghini Gallardo Model" should be 4 - @ui @api + @todo @ui @api Scenario: Product's average rating is correctly recalculated after review's rate change When I delete the "Awesome" product review Then I should be notified that it has been successfully deleted diff --git a/features/admin/product/managing_product_reviews/rejecting_product_review.feature b/features/admin/product/managing_product_reviews/rejecting_product_review.feature index 94e360df3e..afa424dbf8 100644 --- a/features/admin/product/managing_product_reviews/rejecting_product_review.feature +++ b/features/admin/product/managing_product_reviews/rejecting_product_review.feature @@ -10,7 +10,7 @@ Feature: Rejecting a product review And this product has a new review titled "Crap" and rated 1 added by customer "ross@teammike.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Rejecting a product review When I want to browse product reviews And I reject the "Crap" product review diff --git a/features/admin/product/managing_product_variants/adding_product_variant.feature b/features/admin/product/managing_product_variants/adding_product_variant.feature index efaac6f00c..fbb9a30b8e 100644 --- a/features/admin/product/managing_product_variants/adding_product_variant.feature +++ b/features/admin/product/managing_product_variants/adding_product_variant.feature @@ -20,7 +20,7 @@ Feature: Adding a new product variant And I add it Then I should be notified that it has been successfully created And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States" @api @ui Scenario: Adding a new product variant with name @@ -34,9 +34,9 @@ Feature: Adding a new product variant And I add it Then I should be notified that it has been successfully created And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States" - And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Vodka Wyborowa Premium" in "English (United States)" locale - And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Wódka Wyborowa Premium" in "Polish (Poland)" locale +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Vodka Wyborowa Premium" in "English (United States)" locale +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be named "Wódka Wyborowa Premium" in "Polish (Poland)" locale @api @ui Scenario: Adding a new product variant with specific option's value @@ -69,8 +69,8 @@ Feature: Adding a new product variant And I add it Then I should be notified that it has been successfully created And the "VODKA_WYBOROWA_EXQUISITE" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA_EXQUISITE" should be priced at "$100.00" for channel "United States" - And the variant with code "VODKA_WYBOROWA_EXQUISITE" should have an original price of "$120.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_EXQUISITE" should be priced at "$100.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_EXQUISITE" should have an original price of "$120.00" for channel "United States" @api @ui Scenario: Adding a new product variant without shipping required @@ -81,9 +81,9 @@ Feature: Adding a new product variant And I set its "Taste" option to "Orange" And I add it Then I should be notified that it has been successfully created - And the variant with code "VODKA_WYBOROWA_PREMIUM" should not have shipping required +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should not have shipping required And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$100.00" for channel "United States" @api @ui Scenario: Adding a new free product variant @@ -94,7 +94,7 @@ Feature: Adding a new product variant And I add it Then I should be notified that it has been successfully created And the "VODKA_WYBOROWA_PREMIUM" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$0.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_PREMIUM" should be priced at "$0.00" for channel "United States" @api @ui Scenario: Adding a new product variant with minimum price @@ -106,5 +106,5 @@ Feature: Adding a new product variant And I add it Then I should be notified that it has been successfully created And the "VODKA_WYBOROWA" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA" should be priced at "$100.00" for channel "United States" - And the variant with code "VODKA_WYBOROWA" should have minimum price "$50.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA" should be priced at "$100.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA" should have minimum price "$50.00" for channel "United States" diff --git a/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature b/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature index 051607d794..5bc168adc9 100644 --- a/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature +++ b/features/admin/product/managing_product_variants/adding_product_variant_with_only_original_price.feature @@ -18,4 +18,4 @@ Feature: Adding a product variant with only original price And I add it Then I should be notified that it has been successfully created And the "VODKA_WYBOROWA_DELUX" variant of the "Wyborowa Vodka" product should appear in the store - And the variant with code "VODKA_WYBOROWA_DELUX" should be originally priced at "$100.00" for channel "United States" +# And the variant with code "VODKA_WYBOROWA_DELUX" should be originally priced at "$100.00" for channel "United States" diff --git a/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature b/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature index 08dc47350a..da722438be 100644 --- a/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature +++ b/features/admin/product/managing_product_variants/checking_products_in_the_shop_while_editing_their_product_variants.feature @@ -10,7 +10,7 @@ In order to check a product in shop in all channels it is available in And the store has a product "Bugatti" available in "United States" channel And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Accessing product show page in shop from the product variant edit page where product is available in more than one channel Given this product is also available in the "Europe" channel And this product has "Red" variant priced at "$220,000.00" in "Europe" channel @@ -18,14 +18,14 @@ In order to check a product in shop in all channels it is available in And I choose to show this product in the "Europe" channel Then I should see this product in the "Europe" channel in the shop - @ui @no-api + @todo @ui @no-api Scenario: Accessing product show page in shop from the product variant edit page where product is available in one channel Given this product has "Red" variant priced at "$220,000.00" in "United States" channel When I want to modify the "Bugatti" product variant And I choose to show this product in this channel Then I should see this product in the "United States" channel in the shop - @ui @no-api + @todo @ui @no-api Scenario: Being unable to access product show page in shop when the product is disabled Given this product has been disabled When I want to modify the "Bugatti" product variant diff --git a/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature b/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature index 7add26f9ef..fb2bb1696f 100644 --- a/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature +++ b/features/admin/product/managing_product_variants/deleting_multiple_product_variants.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple product variants And this product has "Small PHP Mug", "Medium PHP Mug" and "Big PHP Mug" variants And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple product variants at once When I browse variants of this product And I check the "Small PHP Mug" product variant diff --git a/features/admin/product/managing_product_variants/generating_product_variant_validation.feature b/features/admin/product/managing_product_variants/generating_product_variant_validation.feature index 80272db012..17cbfd4dc9 100644 --- a/features/admin/product/managing_product_variants/generating_product_variant_validation.feature +++ b/features/admin/product/managing_product_variants/generating_product_variant_validation.feature @@ -58,3 +58,10 @@ Feature: Generating product variant generation And I should be notified that code is required for the 2nd variant And I should be notified that prices in all channels must be defined for the 2nd variant And I should not see any variants in the list + + @ui @no-api + Scenario: Trying to remove an existing product variant during generation + Given the product "Wyborowa Vodka" has "Wyborowa Vodka Orange" variant priced at "$40.00" configured with "Orange" option value + When I want to generate new variants for this product + Then I should not be able to remove 1st product variant + And I should be able to remove 2nd product variant diff --git a/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature b/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature index b3c9a680b4..b3954f3d3d 100644 --- a/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature +++ b/features/admin/product/managing_product_variants/sorting_product_variants_within_product_by_position.feature @@ -44,7 +44,7 @@ Feature: Sorting listed product variants from a product by position Scenario: Setting product variant as the first one in the list When I view all variants of the product "Opel Insignia" And I set the position of "Opel Insignia Sedan" to 0 - And I save my new configuration + And I save my new elements order And I view all variants of the product "Opel Insignia" again Then the first variant in the list should have name "Opel Insignia Sedan" @@ -52,6 +52,6 @@ Feature: Sorting listed product variants from a product by position Scenario: Setting product variant as the last one in the list When I view all variants of the product "Opel Insignia" And I set the position of "Opel Insignia Sedan" to 7 - And I save my new configuration + And I save my new elements order And I view all variants of the product "Opel Insignia" again Then the last variant in the list should have name "Opel Insignia Sedan" diff --git a/features/admin/product/managing_products/accessing_stores_product_page.feature b/features/admin/product/managing_products/accessing_stores_product_page.feature index f6dcf8ce5a..7e26ace06d 100644 --- a/features/admin/product/managing_products/accessing_stores_product_page.feature +++ b/features/admin/product/managing_products/accessing_stores_product_page.feature @@ -10,7 +10,7 @@ Feature: Accessing a store's product page And I am logged in as an administrator And I am using "Polish (Poland)" locale for my panel - @ui @no-api + @todo @ui @no-api Scenario: Accessing the product shop page from the admin panel when the product has a translation with a defined slug in the administrator's chosen language Given the locale "Polish (Poland)" is enabled And this product is named "Bulldog francuski T-Shirt" in the "Polish (Poland)" locale @@ -18,7 +18,7 @@ Feature: Accessing a store's product page Then the show product's page button should be enabled And it should be leading to the product's page in the "Polish (Poland)" locale - @ui @no-api + @todo @ui @no-api Scenario: Accessing the product shop page from the admin panel when the product has a translation with a defined slug in the default channel's language Given the locale "French (France)" is enabled And this product is named "Tee-shirt bouledogue français" in the "French (France)" locale @@ -26,7 +26,7 @@ Feature: Accessing a store's product page Then the show product's page button should be enabled And it should be leading to the product's page in the "German (Germany)" locale - @ui @no-api + @todo @ui @no-api Scenario: Accessing the product shop page from the admin panel with using first available locale with slug and enabled in the channel Given the locale "French (France)" is enabled And the store also operates in "French (France)" locale @@ -36,7 +36,7 @@ Feature: Accessing a store's product page Then the show product's page button should be enabled And it should be leading to the product's page in the "French (France)" locale - @ui @no-api + @todo @ui @no-api Scenario: Not being able to access the product shop page from the admin panel when the product has no translations meeting the criteria Given this product has no translations with a defined slug When I want to edit this product diff --git a/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature b/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature index f3084b9a8e..88a6ab1962 100644 --- a/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature +++ b/features/admin/product/managing_products/accessing_variants_management_from_product_edit_page.feature @@ -10,19 +10,19 @@ Feature: Accessing the variants management from the product edit page And this product has option "Model" with values "RS6" and "RS7" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Being able to access the variants list page When I modify the "Audi" product And I go to the variants list Then I should be on the list of this product's variants - @ui @no-api + @todo @ui @no-api Scenario: Being able to access the variant creation page When I modify the "Audi" product And I go to the variant creation page Then I should be on the variant creation page for this product - @ui @no-api + @todo @ui @no-api Scenario: Being able to access the variant generation page When I modify the "Audi" product And I go to the variant generation page diff --git a/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature b/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature index 1a4cf716ae..ca59165399 100644 --- a/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature +++ b/features/admin/product/managing_products/adding_multiple_product_attributes_at_once.feature @@ -10,7 +10,7 @@ Feature: Adding a new integer product attribute And the store has a non-translatable text product attribute "ISBN" And I am logged in as an administrator - @ui @javascript @api + @todo @ui @javascript @api Scenario: Adding two text attributes to a product When I want to create a new configurable product And I specify its code as "HARRY_POTTER_1" diff --git a/features/admin/product/managing_products/adding_product.feature b/features/admin/product/managing_products/adding_product.feature index 0c19302a3f..0564c8e6e1 100644 --- a/features/admin/product/managing_products/adding_product.feature +++ b/features/admin/product/managing_products/adding_product.feature @@ -9,53 +9,70 @@ Feature: Adding a new product And the store has "Standard" shipping category And I am logged in as an administrator - @ui @no-api + @ui @mink:chromedriver @no-api Scenario: Adding a new simple product with price When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" And I name it "Dice Brewing" in "English (United States)" - And I set its slug to "dice-brewing" in "English (United States)" And I set its price to "$10.00" for "United States" channel And I add it Then I should be notified that it has been successfully created And the product "Dice Brewing" should appear in the store - @ui @no-api + @ui @mink:chromedriver @no-api Scenario: Adding a new simple product with discounted price When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" And I name it "Dice Brewing" in "English (United States)" - And I set its slug to "dice-brewing" in "English (United States)" And I set its price to "$10.00" for "United States" channel And I set its original price to "$20.00" for "United States" channel And I add it Then I should be notified that it has been successfully created And the product "Dice Brewing" should appear in the store - @ui @no-api + @ui @mink:chromedriver @no-api Scenario: Adding a new simple Free product When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" And I name it "Dice Brewing" in "English (United States)" - And I set its slug to "dice-brewing" in "English (United States)" And I set its price to "$0.00" for "United States" channel And I add it Then I should be notified that it has been successfully created And the product "Dice Brewing" should appear in the store - @ui @no-api + @ui @mink:chromedriver @no-api Scenario: Adding a new simple product with specific shipping category When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" And I name it "Dice Brewing" in "English (United States)" And I set its price to "$10.00" for "United States" channel - And I set its slug to "dice-brewing" in "English (United States)" And I set its shipping category as "Standard" And I add it Then I should be notified that it has been successfully created And the product "Dice Brewing" should appear in the store - @ui @javascript @api + @ui @mink:chromedriver @no-api + Scenario: Adding a new simple product without shipping required + When I want to create a new simple product + And I specify its code as "BOARD_DICE_BREWING" + And I name it "Dice Brewing" in "English (United States)" + And I set its price to "$10.00" for "United States" channel + And I do not want to have shipping required for this product + And I add it + Then I should be notified that it has been successfully created + And the product "Dice Brewing" should not have shipping required + And the product "Dice Brewing" should appear in the store + + @ui @mink:chromedriver @api + Scenario: Adding a new configurable product without options + When I want to create a new configurable product + And I specify its code as "WHISKEY_GENTLEMEN" + And I name it "Gentleman Jack" in "English (United States)" + And I add it + Then I should be notified that it has been successfully created + And the product "Gentleman Jack" should appear in the store + + @ui @mink:chromedriver @api Scenario: Adding a new configurable product Given the store has a product option "Bottle size" with a code "bottle_size" And this product option has the "0.7" option value with code "bottle_size_medium" @@ -64,30 +81,6 @@ Feature: Adding a new product And I specify its code as "WHISKEY_GENTLEMEN" And I name it "Gentleman Jack" in "English (United States)" And I add the "Bottle size" option to it - And I set its slug to "whiskey/gentleman-jack" in "English (United States)" And I add it Then I should be notified that it has been successfully created And the product "Gentleman Jack" should appear in the store - - @ui @api - Scenario: Adding a new configurable product without options - When I want to create a new configurable product - And I specify its code as "WHISKEY_GENTLEMEN" - And I name it "Gentleman Jack" in "English (United States)" - And I set its slug to "whiskey/gentleman-jack" in "English (United States)" - And I add it - Then I should be notified that it has been successfully created - And the product "Gentleman Jack" should appear in the store - - @ui @no-api - Scenario: Adding a new simple product without shipping required - When I want to create a new simple product - And I specify its code as "BOARD_DICE_BREWING" - And I name it "Dice Brewing" in "English (United States)" - And I set its slug to "dice-brewing" in "English (United States)" - And I set its price to "$10.00" for "United States" channel - And I do not want to have shipping required for this product - And I add it - Then I should be notified that it has been successfully created - And the product "Dice Brewing" should not have shipping required - And the product "Dice Brewing" should appear in the store diff --git a/features/admin/product/managing_products/adding_product_with_associations.feature b/features/admin/product/managing_products/adding_product_with_associations.feature index c80f2428bd..474573287b 100644 --- a/features/admin/product/managing_products/adding_product_with_associations.feature +++ b/features/admin/product/managing_products/adding_product_with_associations.feature @@ -48,5 +48,5 @@ Feature: Adding a new product with associations And I associate as 123 the "LG headphones" and "LG earphones" products And I add it Then I should be notified that it has been successfully created - And this product should have an association 123 with products "LG headphones" and "LG earphones" + And this product should have an association "123" with products "LG headphones" and "LG earphones" And the product "LG G3" should appear in the store diff --git a/features/admin/product/managing_products/adding_product_with_only_original_price.feature b/features/admin/product/managing_products/adding_product_with_only_original_price.feature index 10c2c10568..67e6e31a22 100644 --- a/features/admin/product/managing_products/adding_product_with_only_original_price.feature +++ b/features/admin/product/managing_products/adding_product_with_only_original_price.feature @@ -8,7 +8,7 @@ Feature: Adding a product with only original price Given the store operates on a single channel in "United States" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product without price When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" diff --git a/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature b/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature index 6d9642daa8..11556d81cd 100644 --- a/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature +++ b/features/admin/product/managing_products/adding_product_with_prices_for_multiple_channels.feature @@ -10,7 +10,7 @@ Feature: Adding product with prices for multiple channels And the store operates on another channel named "Web-GB" in "GBP" currency And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Configure prices for each channel and currency while adding a new simple product When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" @@ -23,7 +23,7 @@ Feature: Adding product with prices for multiple channels And product "Dice Brewing" should be priced at $10.00 for channel "Web-US" And product "Dice Brewing" should be priced at £5.00 for channel "Web-GB" - @ui @no-api + @todo @ui @no-api Scenario: Configure prices for each channel while adding a new simple product When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" @@ -33,7 +33,7 @@ Feature: Adding product with prices for multiple channels And I add it Then I should be notified that price must be defined for every channel - @ui @no-api + @todo @ui @no-api Scenario: Require prices only for chosen channels When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" @@ -45,7 +45,7 @@ Feature: Adding product with prices for multiple channels Then I should be notified that it has been successfully created And product "Dice Brewing" should be priced at $10.00 for channel "Web-US" - @ui @no-api + @todo @ui @no-api Scenario: Require prices for all chosen channels When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" @@ -57,7 +57,7 @@ Feature: Adding product with prices for multiple channels And I add it Then I should be notified that price must be defined for every channel - @ui @no-api + @todo @ui @no-api Scenario: Do not specify price while adding a new simple product When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" diff --git a/features/admin/product/managing_products/browsing_products.feature b/features/admin/product/managing_products/browsing_products.feature index eb715d8c75..b43bdec3d7 100644 --- a/features/admin/product/managing_products/browsing_products.feature +++ b/features/admin/product/managing_products/browsing_products.feature @@ -8,7 +8,7 @@ Feature: Browsing products Given the store has "Dice Brewing" and "Eclipse" products And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing defined products When I want to browse products Then I should see 2 products in the list diff --git a/features/admin/product/managing_products/browsing_products_by_taxon.feature b/features/admin/product/managing_products/browsing_products_by_taxon.feature index 81c274af8a..9747079a4e 100644 --- a/features/admin/product/managing_products/browsing_products_by_taxon.feature +++ b/features/admin/product/managing_products/browsing_products_by_taxon.feature @@ -10,14 +10,14 @@ Feature: Browsing products And this product belongs to "Pugs" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing all products Given the store has a product "Doge mascot" When I am browsing products Then I should see a product with name "Young pug" And I should see a product with name "Doge mascot" - @ui @api + @todo @ui @api Scenario: Browsing only products from specified category Given I am browsing products And the store has a product "Colorful mug" diff --git a/features/admin/product/managing_products/deleting_multiple_products.feature b/features/admin/product/managing_products/deleting_multiple_products.feature index 1b2bd5b4f1..200d27b771 100644 --- a/features/admin/product/managing_products/deleting_multiple_products.feature +++ b/features/admin/product/managing_products/deleting_multiple_products.feature @@ -8,7 +8,7 @@ Feature: Deleting multiple products Given the store has "Audi RS5 model", "Audi RS6 model" and "Audi RS7 model" products And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple products at once When I browse products And I check the "Audi RS5 model" product diff --git a/features/admin/product/managing_products/deleting_product.feature b/features/admin/product/managing_products/deleting_product.feature index 454684c458..b42d37bb8a 100644 --- a/features/admin/product/managing_products/deleting_product.feature +++ b/features/admin/product/managing_products/deleting_product.feature @@ -11,7 +11,7 @@ Feature: Deleting a product And this product has one review from customer "john@doe.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted product disappears from the product catalog When I delete the "Toyota GT86 model" product Then I should be notified that it has been successfully deleted diff --git a/features/admin/product/managing_products/deleting_product_with_reviews.feature b/features/admin/product/managing_products/deleting_product_with_reviews.feature index 074502ca89..b9ca48eb1f 100644 --- a/features/admin/product/managing_products/deleting_product_with_reviews.feature +++ b/features/admin/product/managing_products/deleting_product_with_reviews.feature @@ -9,7 +9,7 @@ Feature: Deleting a product with its reviews And this product has one review from customer "john@doe.com" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted product reviews disappear from the product catalog When I delete the "Toyota GT86 model" product Then I should be notified that it has been successfully deleted diff --git a/features/admin/product/managing_products/editing_product.feature b/features/admin/product/managing_products/editing_product.feature index 53f1134270..66a506e473 100644 --- a/features/admin/product/managing_products/editing_product.feature +++ b/features/admin/product/managing_products/editing_product.feature @@ -9,12 +9,12 @@ Feature: Editing a product And the store has a product "Dice Brewing" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Being unable to change code of an existing product When I want to modify the "Dice Brewing" product Then I should not be able to edit its code - @ui @no-api + @todo @ui @no-api Scenario: Renaming a simple product When I want to modify the "Dice Brewing" product And I rename it to "7 Wonders" in "English (United States)" @@ -22,7 +22,7 @@ Feature: Editing a product Then I should be notified that it has been successfully edited And this product name should be "7 Wonders" - @ui @no-api + @todo @ui @no-api Scenario: Renaming a simple product does not change its variant name Given this product only variant was renamed to "Dice Brewing: The Game" When I want to modify this product @@ -31,7 +31,7 @@ Feature: Editing a product And I want to view all variants of this product Then the first variant in the list should have name "Dice Brewing: The Game" - @ui @no-api + @todo @ui @no-api Scenario: Changing a simple product price When I want to modify the "Dice Brewing" product And I change its price to $15.00 for "United States" channel @@ -39,7 +39,7 @@ Feature: Editing a product Then I should be notified that it has been successfully edited And it should be priced at $15.00 for channel "United States" - @ui @no-api + @todo @ui @no-api Scenario: Changing a simple product price When I want to modify the "Dice Brewing" product And I change its price to $7.50 for "United States" channel @@ -49,7 +49,7 @@ Feature: Editing a product And it should be priced at $7.50 for channel "United States" And its original price should be "$15.00" for channel "United States" - @ui @api + @todo @ui @api Scenario: Renaming a configurable product Given the store has a "Wyborowa Vodka" configurable product When I want to modify this product @@ -58,7 +58,7 @@ Feature: Editing a product Then I should be notified that it has been successfully edited And this product name should be "Sobieski Vodka" - @ui @api + @todo @ui @api Scenario: Renaming a configurable product with option Given the store has a "Wyborowa Vodka" configurable product And the store has a product option "Bottle size" with a code "bottle_size" @@ -69,7 +69,7 @@ Feature: Editing a product Then I should be notified that it has been successfully edited And this product name should be "Sobieski Vodka" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Changing options of configurable product without any variant defined Given the store has a "Marvel's T-Shirt" configurable product And the store has a product option "T-Shirt size" with a code "t_shirt_size" @@ -81,7 +81,7 @@ Feature: Editing a product Then I should be notified that it has been successfully edited And this product should have a "T-Shirt color" option - @ui @api + @todo @ui @api Scenario: Being unable to change options of an existing product Given the store has a "Marvel's T-Shirt" configurable product And the store has a product option "T-Shirt size" with a code "t_shirt_size" @@ -91,7 +91,7 @@ Feature: Editing a product When I want to modify the "Marvel's T-Shirt" product Then I should not be able to edit its options - @ui @api + @todo @ui @api Scenario: Enabling product in channel when all its variants already have specified price in this channel Given the store operates on another channel named "Mobile" And the store has a "7 Wonders" configurable product diff --git a/features/admin/product/managing_products/editing_product_attributes.feature b/features/admin/product/managing_products/editing_product_attributes.feature deleted file mode 100644 index 3d8ca4fc5c..0000000000 --- a/features/admin/product/managing_products/editing_product_attributes.feature +++ /dev/null @@ -1,28 +0,0 @@ -@managing_products -Feature: Editing product's attributes - In order to modify product details - As an Administrator - I want to be able to edit product's attributes - - Background: - Given the store operates on a single channel in "United States" - And the store has a product "44 Magnum" - And the store has a text product attribute "Overall length" - And this product has a text attribute "Gun caliber" with value "11 mm" - And I am logged in as an administrator - - @ui @javascript @no-api - Scenario: Seeing message about no new attributes selected - When I want to modify the "44 Magnum" product - And I try to add new attributes - And I save my changes - Then attribute "Gun caliber" of product "44 Magnum" should be "11 mm" - And product "44 Magnum" should have 1 attribute - - @ui @javascript @no-api - Scenario: Seeing message about no new attributes selected after all attributes deletion - When I want to modify the "44 Magnum" product - And I remove its "Gun caliber" attribute - And I try to add new attributes - And I save my changes - Then product "44 Magnum" should not have any attributes diff --git a/features/admin/product/managing_products/editing_product_slug.feature b/features/admin/product/managing_products/editing_product_slug.feature index f34a603f8f..69045abe15 100644 --- a/features/admin/product/managing_products/editing_product_slug.feature +++ b/features/admin/product/managing_products/editing_product_slug.feature @@ -8,7 +8,7 @@ Feature: Editing product's slug Given the store operates on a single channel in "United States" And I am logged in as an administrator - @ui @javascript @api + @todo @ui @javascript @api Scenario: Creating a product with an autogenerated slug When I want to create a new configurable product And I specify its code as "BOARD_MANSION_OF_MADNESS" @@ -16,7 +16,7 @@ Feature: Editing product's slug And I add it Then the slug of the "Mansion of Madness" product should be "mansion-of-madness" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Creating a product with a custom slug When I want to create a new configurable product And I specify its code as "BOARD_MANSION_OF_MADNESS" @@ -25,13 +25,13 @@ Feature: Editing product's slug And I add it Then the slug of the "Mansion of Madness" product should be "mom-board-game" - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled slug field when editing a product Given the store has a product "Mansion of Madness" When I want to modify this product Then the slug field should not be editable - @ui @javascript @api + @todo @ui @javascript @api Scenario: Prevent from editing a slug while changing a product name Given the store has a product "Mansion of Madness" When I want to modify this product @@ -39,7 +39,7 @@ Feature: Editing product's slug And I save my changes Then the slug of the "Mansion of Madness: Second Edition" product should still be "mansion-of-madness" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Automatically changing a product's slug while editing a product's name Given the store has a product "Mansion of Madness" When I want to modify this product @@ -48,7 +48,7 @@ Feature: Editing product's slug And I save my changes Then the slug of the "Small World" product should be "small-world" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Manually changing a product's slug while editing a product's name Given the store has a product "Mansion of Madness" When I want to modify this product diff --git a/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature b/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature index 40b0cc6b22..b05fbdd7b2 100644 --- a/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature +++ b/features/admin/product/managing_products/editing_product_slug_in_multiple_locales.feature @@ -10,7 +10,7 @@ Feature: Editing product's slug in multiple locales And the store is also available in "Polish (Poland)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Creating a product with custom slugs When I want to create a new configurable product And I specify its code as "PUG_PUGGINTON_PLUSHIE" @@ -22,7 +22,7 @@ Feature: Editing product's slug in multiple locales Then the slug of the "Pug Pugginton Plushie" product should be "sir-pugginton" in the "English (United States)" locale And the slug of the "Pug Pugginton Plushie" product should be "pan-mopsinski" in the "Polish (Poland)" locale - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Creating a product with autogenerated slugs When I want to create a new configurable product And I specify its code as "PUG_PUGGINTON_PLUSHIE" @@ -32,14 +32,14 @@ Feature: Editing product's slug in multiple locales Then the slug of the "Pug Pugginton Plushie" product should be "pug-pugginton-plushie" in the "English (United States)" locale And the slug of the "Pug Pugginton Plushie" product should be "pluszak-mops-mopsinski" in the "Polish (Poland)" locale - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled slug fields when editing a product Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale When I want to modify this product Then the slug field in "English (United States)" should not be editable And the slug field in "Polish (Poland)" also should not be editable - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Slugs don't get updated while changing product's names Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale When I want to modify this product @@ -49,7 +49,7 @@ Feature: Editing product's slug in multiple locales Then this product should still have slug "pug-pugginton-plushie" in "English (United States)" locale And this product should still have slug "pluszak-mops-mopsinski" in "Polish (Poland)" locale - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Enabling automatic slugs update on product's names change Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale When I want to modify this product @@ -61,7 +61,7 @@ Feature: Editing product's slug in multiple locales Then this product should have slug "pug-pugston-the-third-plushie" in "English (United States)" locale And this product should have slug "pluszak-mops-mopsak-trzeci" in "Polish (Poland)" locale - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Manually modifying slugs on product's names change Given the store has a product named "Pug Pugginton Plushie" in "English (United States)" locale and "Pluszak Mops Mopsiński" in "Polish (Poland)" locale When I want to modify this product diff --git a/features/admin/product/managing_products/filtering_products_by_channel.feature b/features/admin/product/managing_products/filtering_products_by_channel.feature index 990001a747..542061ef84 100644 --- a/features/admin/product/managing_products/filtering_products_by_channel.feature +++ b/features/admin/product/managing_products/filtering_products_by_channel.feature @@ -12,7 +12,7 @@ Feature: Filtering products by a channel And the store also has a product "HP Spectre" in channel "Web-US" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering products by a chosen channel When I browse products And I choose "Web-EU" as a channel filter @@ -22,7 +22,7 @@ Feature: Filtering products by a channel And I should see a product with name "MacBook Pro" But I should not see any product with name "HP Spectre" - @ui @api + @todo @ui @api Scenario: Filtering products by a chosen channel When I browse products And I choose "Web-US" as a channel filter diff --git a/features/admin/product/managing_products/adding_product_with_date_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_date_attribute.feature similarity index 100% rename from features/admin/product/managing_products/adding_product_with_date_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_date_attribute.feature diff --git a/features/admin/product/managing_products/adding_product_with_datetime_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_datetime_attribute.feature similarity index 100% rename from features/admin/product/managing_products/adding_product_with_datetime_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_datetime_attribute.feature diff --git a/features/admin/product/managing_products/adding_product_with_float_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_float_attribute.feature similarity index 94% rename from features/admin/product/managing_products/adding_product_with_float_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_float_attribute.feature index 8d19c932b0..51372b4750 100644 --- a/features/admin/product/managing_products/adding_product_with_float_attribute.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_float_attribute.feature @@ -9,11 +9,12 @@ Feature: Adding a new product with a float attribute And the store has a non-translatable float product attribute "Display Size" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a float attribute to a product When I want to create a new configurable product And I specify its code as "display_size" And I name it "Smartphone" in "English (United States)" + And I add the "Display Size" attribute to it And I set its non-translatable "Display Size" attribute to 12.5 And I add it Then I should be notified that it has been successfully created diff --git a/features/admin/product/managing_products/adding_product_with_integer_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_integer_attribute.feature similarity index 91% rename from features/admin/product/managing_products/adding_product_with_integer_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_integer_attribute.feature index 4226470be4..66dda909f6 100644 --- a/features/admin/product/managing_products/adding_product_with_integer_attribute.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_integer_attribute.feature @@ -15,7 +15,8 @@ Feature: Adding a new product with an integer attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" - And I set its "Production year" attribute to 1955 in "English (United States)" + And I add the "Production year" attribute to it + And I set the "Production year" attribute value to 1955 in "English (United States)" And I add it Then I should be notified that it has been successfully created And the product "44 Magnum" should appear in the store @@ -26,6 +27,7 @@ Feature: Adding a new product with an integer attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" + And I add the "Weight" attribute to it And I set its non-translatable "Weight" attribute to 10 And I add it Then I should be notified that it has been successfully created diff --git a/features/admin/product/managing_products/adding_product_with_percent_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_percent_attribute.feature similarity index 91% rename from features/admin/product/managing_products/adding_product_with_percent_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_percent_attribute.feature index 7063880eb2..cd85a2dca0 100644 --- a/features/admin/product/managing_products/adding_product_with_percent_attribute.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_percent_attribute.feature @@ -15,7 +15,8 @@ Feature: Adding a new product with a percent attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" - And I set its "Awesomeness rating" attribute to 80 in "English (United States)" + And I add the "Awesomeness rating" attribute to it + And I set the "Awesomeness rating" attribute value to 80 in "English (United States)" And I add it Then I should be notified that it has been successfully created And the product "44 Magnum" should appear in the store @@ -26,6 +27,7 @@ Feature: Adding a new product with a percent attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" + And I add the "Accuracy" attribute to it And I set its non-translatable "Accuracy" attribute to 95 And I add it Then I should be notified that it has been successfully created diff --git a/features/admin/product/managing_products/adding_product_with_select_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_select_attribute.feature similarity index 98% rename from features/admin/product/managing_products/adding_product_with_select_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_select_attribute.feature index f4b75295ac..57930df3a0 100644 --- a/features/admin/product/managing_products/adding_product_with_select_attribute.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_select_attribute.feature @@ -9,7 +9,7 @@ Feature: Adding a new product with a select attribute And the store has a non-translatable select product attribute "Mug material" with value "Ceramic" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a product with a select attribute with choices in different locales When I want to create a new configurable product And I specify its code as "mug" diff --git a/features/admin/product/managing_products/adding_product_with_text_attribute.feature b/features/admin/product/managing_products/managing_attributes/adding_product_with_text_attribute.feature similarity index 85% rename from features/admin/product/managing_products/adding_product_with_text_attribute.feature rename to features/admin/product/managing_products/managing_attributes/adding_product_with_text_attribute.feature index c4ceea69c5..1de5f95905 100644 --- a/features/admin/product/managing_products/adding_product_with_text_attribute.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_product_with_text_attribute.feature @@ -16,7 +16,8 @@ Feature: Adding a new product with text attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" - And I set its "Gun caliber" attribute to "11 mm" in "English (United States)" + And I add the "Gun caliber" attribute + And I set the "Gun caliber" attribute value to "11 mm" in "English (United States)" And I add it Then I should be notified that it has been successfully created And the product "44 Magnum" should appear in the store @@ -27,6 +28,7 @@ Feature: Adding a new product with text attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" + And I add the "Author" attribute to it And I set its non-translatable "Author" attribute to "Colt" And I add it Then I should be notified that it has been successfully created @@ -38,8 +40,10 @@ Feature: Adding a new product with text attribute When I want to create a new configurable product And I specify its code as "44_MAGNUM" And I name it "44 Magnum" in "English (United States)" - And I set its "Gun caliber" attribute to "11 mm" in "English (United States)" - And I set its "Overall length" attribute to "30.5 cm" in "English (United States)" + And I add the "Gun caliber" attribute + And I set the "Gun caliber" attribute value to "11 mm" in "English (United States)" + And I add the "Overall length" attribute + And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)" And I remove its "Gun caliber" attribute And I add it Then I should be notified that it has been successfully created diff --git a/features/admin/product/managing_products/adding_select_attribute_in_different_locales.feature b/features/admin/product/managing_products/managing_attributes/adding_select_attribute_in_different_locales.feature similarity index 100% rename from features/admin/product/managing_products/adding_select_attribute_in_different_locales.feature rename to features/admin/product/managing_products/managing_attributes/adding_select_attribute_in_different_locales.feature diff --git a/features/admin/product/managing_products/adding_text_attribute_in_different_locales.feature b/features/admin/product/managing_products/managing_attributes/adding_text_attribute_in_different_locales.feature similarity index 76% rename from features/admin/product/managing_products/adding_text_attribute_in_different_locales.feature rename to features/admin/product/managing_products/managing_attributes/adding_text_attribute_in_different_locales.feature index 04aed9be9e..96589638c7 100644 --- a/features/admin/product/managing_products/adding_text_attribute_in_different_locales.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_text_attribute_in_different_locales.feature @@ -8,7 +8,7 @@ Feature: Adding text attributes in different locales to a product Given the store operates on a channel named "Web" And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales And it uses the "English (United States)" locale by default - And the store has a product "Symfony Mug" + And the store has a "Symfony Mug" configurable product And the store has a text product attribute "Mug material" And I am logged in as an administrator @@ -17,8 +17,9 @@ Feature: Adding text attributes in different locales to a product When I want to create a new configurable product And I specify its code as "mug" And I name it "PHP Mug" in "English (United States)" - And I set its "Mug material" attribute to "Wood" in "English (United States)" - And I set its "Mug material" attribute to "Drewno" in "Polish (Poland)" + And I add the "Mug material" attribute + And I set the "Mug material" attribute value to "Wood" in "English (United States)" + And I set the "Mug material" attribute value to "Drewno" in "Polish (Poland)" And I add it Then I should be notified that it has been successfully created And the product "PHP Mug" should appear in the store @@ -28,8 +29,9 @@ Feature: Adding text attributes in different locales to a product @ui @mink:chromedriver @api Scenario: Adding a text attribute in different locales to an existing product When I want to modify the "Symfony Mug" product - And I set its "Mug material" attribute to "Wood" in "English (United States)" - And I set its "Mug material" attribute to "Drewno" in "Polish (Poland)" + And I add the "Mug material" attribute + And I set the "Mug material" attribute value to "Wood" in "English (United States)" + And I set the "Mug material" attribute value to "Drewno" in "Polish (Poland)" And I save my changes Then I should be notified that it has been successfully edited And attribute "Mug material" of product "Symfony Mug" should be "Wood" in "English (United States)" diff --git a/features/admin/product/managing_products/adding_text_attributes_to_existing_product.feature b/features/admin/product/managing_products/managing_attributes/adding_text_attributes_to_existing_product.feature similarity index 77% rename from features/admin/product/managing_products/adding_text_attributes_to_existing_product.feature rename to features/admin/product/managing_products/managing_attributes/adding_text_attributes_to_existing_product.feature index 37e9a9f3a6..cac95eaddc 100644 --- a/features/admin/product/managing_products/adding_text_attributes_to_existing_product.feature +++ b/features/admin/product/managing_products/managing_attributes/adding_text_attributes_to_existing_product.feature @@ -6,14 +6,15 @@ Feature: Adding attributes to an existing product Background: Given the store operates on a single channel in "United States" - And the store has a product "44 Magnum" + And the store has a "44 Magnum" configurable product And the store has a text product attribute "Overall length" And I am logged in as an administrator @ui @mink:chromedriver @api Scenario: Adding a text attribute to an existing product When I want to modify the "44 Magnum" product - And I set its "Overall length" attribute to "30.5 cm" in "English (United States)" + And I add the "Overall length" attribute to it + And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)" And I save my changes Then I should be notified that it has been successfully edited And attribute "Overall length" of product "44 Magnum" should be "30.5 cm" @@ -22,7 +23,8 @@ Feature: Adding attributes to an existing product Scenario: Adding another text attribute to an existing product Given this product has a text attribute "Gun caliber" with value "11 mm" in "English (United States)" locale When I want to modify the "44 Magnum" product - And I set its "Overall length" attribute to "30.5 cm" in "English (United States)" + And I add the "Overall length" attribute to it + And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)" And I save my changes Then I should be notified that it has been successfully edited And attribute "Gun caliber" of product "44 Magnum" should be "11 mm" @@ -31,7 +33,8 @@ Feature: Adding attributes to an existing product @ui @mink:chromedriver @api Scenario: Adding and removing text attributes on product update page When I want to modify the "44 Magnum" product - And I set its "Overall length" attribute to "30.5 cm" in "English (United States)" + And I add the "Overall length" attribute to it + And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)" And I remove its "Overall length" attribute And I save my changes Then I should be notified that it has been successfully edited @@ -41,7 +44,8 @@ Feature: Adding attributes to an existing product Scenario: Adding and removing after saving text attributes on product update page Given this product has a text attribute "Gun caliber" with value "11 mm" in "English (United States)" locale When I want to modify the "44 Magnum" product - And I set its "Overall length" attribute to "30.5 cm" in "English (United States)" + And I add the "Overall length" attribute to it + And I set the "Overall length" attribute value to "30.5 cm" in "English (United States)" And I save my changes And I remove its "Gun caliber" attribute And I save my changes diff --git a/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature b/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature index cf0f4fc3a4..3e31ed4795 100644 --- a/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature +++ b/features/admin/product/managing_products/modifying_taxons_assigned_to_an_existing_product.feature @@ -12,13 +12,13 @@ Feature: Modifying taxons assigned to an existing product And the product "T-Shirt" belongs to taxon "Clothes" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Modifying taxons assigned to a product When I change that the "T-Shirt" product does not belong to the "Clothes" taxon And I add "T-Shirts" taxon to the "T-Shirt" product Then the product "T-Shirt" should have the "T-Shirts" taxon - @ui @api + @todo @ui @api Scenario: Adding taxons to product When I add "Clothes" taxon to the "Shirt" product Then the product "Shirt" should have the "Clothes" taxon diff --git a/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature b/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature index 8cad82456b..89141b3a1d 100644 --- a/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature +++ b/features/admin/product/managing_products/preventing_deletion_of_purchased_product.feature @@ -14,13 +14,13 @@ Feature: Preventing deletion of purchased product And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Purchased product cannot be deleted When I try to delete the "Toyota GT86 model" product Then I should be notified that this product is in use and cannot be deleted And this product should still exist in the product catalog - @ui @api + @todo @ui @api Scenario: Purchased product images should be kept Given the store has a product "Lamborghini Gallardo Model" And this product has an image "lamborghini.jpg" with "thumbnail" type diff --git a/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature b/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature index 8ab868842a..4a71b8fc5a 100644 --- a/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature +++ b/features/admin/product/managing_products/preventing_xss_attack_while_adding_new_product.feature @@ -10,12 +10,12 @@ Feature: Preventing a potential XSS attack while adding a new product And the store has "No XSS" taxonomy And I am logged in as an administrator - @ui @javascript @no-api + @ui @mink:chromedriver @no-api Scenario: Preventing a potential XSS attack while adding new product When I want to create a new simple product Then I should be able to name it "No XSS" in "English (United States)" - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Preventing a potential XSS attack while choosing main taxon for a new product When I want to create a new simple product Then I should be able to choose main taxon "No XSS" diff --git a/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature b/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature index 2b058d1544..491591b508 100644 --- a/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature +++ b/features/admin/product/managing_products/preventing_xss_attack_while_editing_product.feature @@ -10,7 +10,7 @@ Feature: Preventing a potential XSS attack while selecting similar product And the store has "" and "LG headphones" products And I am logged in as an administrator - @ui @javascript @no-api + @ui @mink:chromedriver @no-api Scenario: Preventing a potential XSS attack while editing product When I want to create a new simple product Then I should be able to associate as "Accessories" the "LG headphones" product diff --git a/features/admin/product/managing_products/product_validation.feature b/features/admin/product/managing_products/product_validation.feature index b3f8a896f6..25370a1b30 100644 --- a/features/admin/product/managing_products/product_validation.feature +++ b/features/admin/product/managing_products/product_validation.feature @@ -13,7 +13,7 @@ Feature: Products validation And this product attribute has set min value as 3 and max value as 30 And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product without specifying its code When I want to create a new simple product And I name it "Dice Brewing" in "English (United States)" @@ -29,7 +29,7 @@ Feature: Products validation And I try to save my changes Then I should be notified that the locale is not available - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product with duplicated code among products Given the store has a product "7 Wonders" with code "AWESOME_GAME" When I want to create a new simple product @@ -40,7 +40,7 @@ Feature: Products validation Then I should be notified that code has to be unique And product with name "Dice Brewing" should not be added - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product with duplicated code among product variants Given the store has a product "7 Wonders" And this product has "7 Wonders: Cities" variant priced at "$30.00" identified by "AWESOME_GAME" @@ -52,7 +52,7 @@ Feature: Products validation Then I should be notified that simple product code has to be unique And product with name "Dice Brewing" should not be added - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product without specifying its slug When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" @@ -63,7 +63,7 @@ Feature: Products validation Then I should be notified that slug is required And product with name "Dice Brewing" should not be added - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product without specifying its name When I want to create a new simple product And I specify its code as "BOARD_DICE_BREWING" @@ -72,7 +72,7 @@ Feature: Products validation Then I should be notified that name is required And product with code "BOARD_DICE_BREWING" should not be added - @ui @no-api + @todo @ui @no-api Scenario: Adding a new simple product without specifying its price for every channel Given the store operates on another channel named "Web-GB" When I want to create a new simple product @@ -85,7 +85,7 @@ Feature: Products validation Then I should be notified that price must be defined for every channel And product with code "BOARD_DICE_BREWING" should not be added - @ui @api + @todo @ui @api Scenario: Adding a new configurable product without specifying its code When I want to create a new configurable product And I name it "Dice Brewing" in "English (United States)" @@ -93,7 +93,7 @@ Feature: Products validation Then I should be notified that code is required And product with name "Dice Brewing" should not be added - @ui @api + @todo @ui @api Scenario: Adding a new configurable product with too long code When I want to create a new configurable product And I name it "Dice Brewing" in "English (United States)" @@ -101,7 +101,7 @@ Feature: Products validation And I try to add it Then I should be notified that code is too long - @ui @api + @todo @ui @api Scenario: Adding a new configurable product with duplicated code Given the store has a product "7 Wonders" with code "AWESOME_GAME" When I want to create a new configurable product @@ -111,7 +111,7 @@ Feature: Products validation Then I should be notified that code has to be unique And product with name "Dice Brewing" should not be added - @ui @api + @todo @ui @api Scenario: Adding a new configurable product without specifying its name When I want to create a new configurable product And I specify its code as "BOARD_DICE_BREWING" @@ -120,7 +120,7 @@ Feature: Products validation Then I should be notified that name is required And product with code "BOARD_DICE_BREWING" should not be added - @ui @api + @todo @ui @api Scenario: Trying to set too long meta keywords for a product Given the store has a "Dice Brewing" product When I want to modify this product @@ -128,7 +128,7 @@ Feature: Products validation And I try to save my changes Then I should be notified that meta keywords are too long - @ui @api + @todo @ui @api Scenario: Trying to set too long meta keywords for a product Given the store has a "Dice Brewing" product When I want to modify this product @@ -136,7 +136,7 @@ Feature: Products validation And I try to save my changes Then I should be notified that meta description is too long - @ui @api + @todo @ui @api Scenario: Trying to remove name from existing product Given the store has a "Dice Brewing" product When I want to modify this product @@ -145,7 +145,7 @@ Feature: Products validation Then I should be notified that name is required And this product should still be named "Dice Brewing" - @ui @api + @todo @ui @api Scenario: Trying to assign new channel to an existing configurable product without specifying its all variant prices for this channel Given the store has a "7 Wonders" configurable product And this product has "7 Wonders: Cities" variant priced at "$30.00" @@ -156,7 +156,7 @@ Feature: Products validation And I save my changes Then I should be notified that I have to define product variants' prices for newly assigned channels first - @ui @api + @todo @ui @api Scenario: Adding a new product with duplicated slug Given the store has a "7 Wonders" configurable product with "7-wonders" slug When I want to create a new configurable product @@ -167,7 +167,7 @@ Feature: Products validation Then I should be notified that slug has to be unique And product with code "7-WONDERS-BABEL" should not be added - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Trying to add a new product with a text attribute without specifying its value in default locale When I want to create a new configurable product And I specify its code as "X-18-MUG" @@ -178,7 +178,7 @@ Feature: Products validation Then I should be notified that I have to define the "Mug material" attribute in "English (United States)" And product with code "X-18-MUG" should not be added - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Trying to add a new product with a text attribute without specifying its value in additional locale with proper length When I want to create a new configurable product And I specify its code as "X-18-MUG" @@ -189,7 +189,7 @@ Feature: Products validation Then I should be notified that the "Mug material" attribute in "Polish (Poland)" should be longer than 3 And product with code "X-18-MUG" should not be added - @ui @javascript @api + @todo @ui @javascript @api Scenario: Trying to add a text attribute in different locales to an existing product without specifying its value in default locale When I want to modify the "Symfony Mug" product And I set its "Mug material" attribute to "Drewno" in "Polish (Poland)" @@ -197,7 +197,7 @@ Feature: Products validation And I save my changes Then I should be notified that I have to define the "Mug material" attribute in "English (United States)" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Trying to add a text attribute in different locales to an existing product without specifying its value in additional locale with proper length When I want to modify the "Symfony Mug" product And I set its "Mug material" attribute to "Dr" in "Polish (Poland)" diff --git a/features/admin/product/managing_products/removing_images_of_product.feature b/features/admin/product/managing_products/removing_images_of_product.feature index 3f9aa42f14..3947e32a5b 100644 --- a/features/admin/product/managing_products/removing_images_of_product.feature +++ b/features/admin/product/managing_products/removing_images_of_product.feature @@ -6,6 +6,7 @@ Feature: Removing images of an existing product Background: Given I am logged in as an administrator + And the store operates on a single channel @ui @mink:chromedriver @api Scenario: Removing a single image of a simple product diff --git a/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature b/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature index 63569065b2..86f15a91f3 100644 --- a/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature +++ b/features/admin/product/managing_products/removing_product_price_after_channel_deletion.feature @@ -12,7 +12,7 @@ Feature: Removing a product's price after channel deletion And this product is also priced at "£5.00" in "Web-GB" channel And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Removing a product's price after corresponding channel deletion When channel "Web-GB" has been deleted Then product "Dice Brewing" should be priced at $10.00 for channel "Web-US" diff --git a/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature b/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature index baa7681125..0a56dbfcad 100644 --- a/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature +++ b/features/admin/product/managing_products/removing_product_price_from_obsolete_channel.feature @@ -13,7 +13,7 @@ Feature: Removing a product's price from the channel where it is not available i And this product is disabled in "Web-GB" channel And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Removing a product's price from disabled channel Given the channel "Web-GB" has been disabled When I want to modify the "Dice Brewing" product @@ -22,7 +22,7 @@ Feature: Removing a product's price from the channel where it is not available i Then I should not have configured price for "Web-GB" channel But I should have original price equal to "£70.00" in "Web-GB" channel - @ui @no-api + @todo @ui @no-api Scenario: Removing a product's price from obsolete channel Given this product is disabled in "Web-GB" channel When I want to modify the "Dice Brewing" product diff --git a/features/admin/product/managing_products/select_taxons_for_new_product.feature b/features/admin/product/managing_products/select_taxons_for_new_product.feature index c063c64922..e152c046a8 100644 --- a/features/admin/product/managing_products/select_taxons_for_new_product.feature +++ b/features/admin/product/managing_products/select_taxons_for_new_product.feature @@ -10,7 +10,7 @@ Feature: Select taxon for a new product And I am logged in as an administrator And I am using "English (United Kingdom)" locale for my panel - @ui @javascript @api + @todo @ui @javascript @api Scenario: Specifying main taxon for configurable product When I want to create a new configurable product And I choose main taxon "Sad" @@ -21,7 +21,7 @@ Feature: Select taxon for a new product Then I should be notified that it has been successfully created And main taxon of product "Gentleman Jack" should be "Sad" - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Specifying main taxon for simple product When I want to create a new simple product And I choose main taxon "Sad" diff --git a/features/admin/product/managing_products/select_taxons_for_product.feature b/features/admin/product/managing_products/select_taxons_for_product.feature index 1fdc8ec416..f2ca69633a 100644 --- a/features/admin/product/managing_products/select_taxons_for_product.feature +++ b/features/admin/product/managing_products/select_taxons_for_product.feature @@ -12,7 +12,7 @@ Feature: Select taxon for an existing product And I am logged in as an administrator And I am using "English (United Kingdom)" locale for my panel - @ui @javascript @api + @todo @ui @javascript @api Scenario: Specifying main taxon for configurable product When I want to modify the "T-Shirt Banana" product And I choose main taxon "T-Shirts" @@ -20,11 +20,10 @@ Feature: Select taxon for an existing product Then I should be notified that it has been successfully edited And main taxon of product "T-Shirt Banana" should be "T-Shirts" - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Specifying main taxon for simple product When I want to modify the "T-Shirt Batman" product And I choose main taxon "Sad" And I save my changes Then I should be notified that it has been successfully edited And main taxon of product "T-Shirt Batman" should be "Sad" - diff --git a/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature b/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature index 00f5743882..e24d914606 100644 --- a/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature +++ b/features/admin/product/managing_products/selecting_main_taxons_for_product_in_a_different_locales.feature @@ -17,7 +17,7 @@ Feature: Selecting main taxon for product in different locales And the store has a product "T-Shirt Batman" And I am logged in as an administrator - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Choosing only taxons from the Polish locale Given I am using "Polish (Poland)" locale for my panel When I want to choose main taxon for product "T-Shirt Batman" @@ -25,7 +25,7 @@ Feature: Selecting main taxon for product in different locales And I should be able to choose taxon "Woman-T-Shirts_PL" from the list And I should not be able to choose taxon "Woman-T-Shirts_UA" from the list - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Choosing only taxons from the French locale Given I am using "French (France)" locale for my panel When I want to choose main taxon for product "T-Shirt Batman" @@ -33,7 +33,7 @@ Feature: Selecting main taxon for product in different locales And I should be able to choose taxon "Woman-T-Shirts_FR" from the list And I should not be able to choose taxon "Woman-T-Shirts_UA" from the list - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Choosing only taxons from the German locale Given I am using "German (Germany)" locale for my panel When I want to choose main taxon for product "T-Shirt Batman" diff --git a/features/admin/product/managing_products/sorting_products.feature b/features/admin/product/managing_products/sorting_products.feature index 6e1b076594..eb38f7fbb8 100644 --- a/features/admin/product/managing_products/sorting_products.feature +++ b/features/admin/product/managing_products/sorting_products.feature @@ -16,14 +16,14 @@ Feature: Sorting listed products And this product is named "Ekstremalny Mops" in the "Polish" locale And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Products are sorted by ascending codes by default Given I am browsing products Then I should see 3 products in the list And I should see a product with code "L_PUG" But the first product on the list should have code "B_PUG" - @ui @api + @todo @ui @api Scenario: Changing the codes sorting order Given I am browsing products When I switch the way products are sorted descending by code @@ -31,7 +31,7 @@ Feature: Sorting listed products And I should see a product with code "B_PUG" But the first product on the list should have code "X_PUG" - @ui @api + @todo @ui @api Scenario: Products can be sorted by their names Given I am browsing products When I start sorting products by name @@ -39,7 +39,7 @@ Feature: Sorting listed products And I should see a product with name "Xtreme Pug" But the first product on the list should have name "Berserk Pug" - @ui @api + @todo @ui @api Scenario: Changing the names sorting order Given I am browsing products When the products are already sorted ascending by name @@ -48,7 +48,7 @@ Feature: Sorting listed products And I should see a product with name "Berserk Pug" But the first product on the list should have name "Xtreme Pug" - @ui @api + @todo @ui @api Scenario: Sort products ascending by name from chosen locale translations When I change my locale to "Polish (Poland)" And I browse products @@ -56,7 +56,7 @@ Feature: Sorting listed products Then I should see 3 products in the list And the first product on the list should have name "Ekstremalny Mops" - @ui @api + @todo @ui @api Scenario: Sort products descending by name from chosen locale translations When I change my locale to "Polish (Poland)" And I browse products @@ -65,7 +65,7 @@ Feature: Sorting listed products Then I should see 3 products in the list And the first product on the list should have name "Szałowy Mops" - @ui @api @no-postgres + @todo @ui @api @no-postgres Scenario: Missing translations are sorted as first when sorting by name ascending When I change my locale to "Polish" And I browse products @@ -74,7 +74,7 @@ Feature: Sorting listed products 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 @api @no-postgres + @todo @ui @api @no-postgres Scenario: Missing translation are sorted as last when sorting by name descending When I change my locale to "Polish" And I browse products diff --git a/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature b/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature index 0e9c3496b2..79a4bc039f 100644 --- a/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature +++ b/features/admin/product/managing_products/sorting_products_within_a_taxon_by_position.feature @@ -29,7 +29,7 @@ Feature: Sorting listed products from a taxon by position And the store has a product "Ultimate Pug" in the "Soft Toys" taxon at 19th position And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Setting two products to position -1 on the non-last page When I am browsing the 1st page of products from "Soft Toys" taxon And I set the position of "Old pug" to "-1" @@ -39,7 +39,7 @@ Feature: Sorting listed products from a taxon by position Then the one before last product on the list should have name "Old pug" with position 18 And the last product on the list should have name "Young pug" with position 19 - @ui @no-api + @todo @ui @no-api Scenario: Setting two products to position -1 on the last page When I am browsing the 2nd page of products from "Soft Toys" taxon And I set the position of "Pug XL" to "-1" @@ -48,7 +48,7 @@ Feature: Sorting listed products from a taxon by position Then the one before last product on the list should have name "Pug XL" with position 18 And the last product on the list should have name "Pug XS" with position 19 - @ui @no-api + @todo @ui @no-api Scenario: Setting two products to the already occupied position on the other page When I am browsing the 1st page of products from "Soft Toys" taxon And I set the position of "Old pug" to "15" @@ -64,7 +64,7 @@ Feature: Sorting listed products from a taxon by position And the 7th product on this page should be named "Pug Master" And this product should be at position 16 - @ui @no-api + @todo @ui @no-api Scenario: Setting two products to the already occupied position on the same page When I am browsing the 2nd page of products from "Soft Toys" taxon And I set the position of "Puglet" to "15" @@ -80,7 +80,7 @@ Feature: Sorting listed products from a taxon by position And the 7th product on this page should be named "Pug Master" And this product should be at position 16 - @ui @no-api + @todo @ui @no-api Scenario: Setting two products to the positions overflowing the max available position on the non-last page When I am browsing the 1st page of products from "Soft Toys" taxon And I set the position of "Old pug" to "25" @@ -90,7 +90,7 @@ Feature: Sorting listed products from a taxon by position Then the one before last product on the list should have name "Old pug" with position 18 And the last product on the list should have name "Young pug" with position 19 - @ui @no-api + @todo @ui @no-api Scenario: Setting two products to the positions overflowing the max available position on the last page When I am browsing the 2nd page of products from "Soft Toys" taxon And I set the position of "Puglet" to "25" @@ -100,14 +100,14 @@ Feature: Sorting listed products from a taxon by position Then the one before last product on the list should have name "Puglet" with position 18 And the last product on the list should have name "Pug XL" with position 19 - @ui @api + @todo @ui @api Scenario: New product is added as last one Given I added a product "Big pug" And I assigned this product to "Soft Toys" taxon When I am browsing the 3rd page of products from "Soft Toys" taxon Then the last product on the list within this taxon should have name "Big pug" - @ui @api + @todo @ui @api Scenario: Product with position 0 is set as the first one When I am browsing products from "Soft Toys" taxon And I set the position of "Young pug" to 0 @@ -115,20 +115,20 @@ Feature: Sorting listed products from a taxon by position And I go to the 1st page of products from "Soft Toys" taxon Then the first product on the list within this taxon should have name "Young pug" - @ui @api + @todo @ui @api Scenario: Being unable to use a non-numeric string as a product position Given I am browsing products from "Soft Toys" taxon When I set the position of "Young pug" to "test" And I save my new configuration Then I should be notified that the position "test" is invalid - @ui @api + @todo @ui @api Scenario: Sort products in descending order When I am browsing products from "Soft Toys" taxon And I sort this taxon's products "descending" by "position" Then the first product on the list within this taxon should have name "Ultimate Pug" - @ui @api + @todo @ui @api Scenario: Products are sorted by position in ascending order by default When I am browsing products from "Soft Toys" taxon Then the first product on the list within this taxon should have name "Old pug" diff --git a/features/admin/product/managing_products/toggling_inventory_on_product.feature b/features/admin/product/managing_products/toggling_inventory_on_product.feature index 79d54d924d..4724f797ab 100644 --- a/features/admin/product/managing_products/toggling_inventory_on_product.feature +++ b/features/admin/product/managing_products/toggling_inventory_on_product.feature @@ -8,7 +8,7 @@ Feature: Toggling the inventory tracking Given the store has a product "Dice Brewing" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Disabling inventory for a simple product Given the "Dice Brewing" product is tracked by the inventory When I want to modify the "Dice Brewing" product @@ -17,7 +17,7 @@ Feature: Toggling the inventory tracking Then I should be notified that it has been successfully edited And inventory of this product should not be tracked - @ui @no-api + @todo @ui @no-api Scenario: Enabling inventory for a simple product When I want to modify the "Dice Brewing" product And I enable its inventory tracking diff --git a/features/admin/product/managing_products/toggling_product.feature b/features/admin/product/managing_products/toggling_product.feature index cc8bd11389..a1666fd14b 100644 --- a/features/admin/product/managing_products/toggling_product.feature +++ b/features/admin/product/managing_products/toggling_product.feature @@ -8,7 +8,7 @@ Feature: Toggling the simple product Given the store has a product "Dice Brewing" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Disabling a simple product Given the "Dice Brewing" product is enabled When I want to modify the "Dice Brewing" product @@ -17,7 +17,7 @@ Feature: Toggling the simple product Then I should be notified that it has been successfully edited And this product should be disabled along with its variant - @ui @no-api + @todo @ui @no-api Scenario: Enabling a simple product Given the "Dice Brewing" product is disabled When I want to modify the "Dice Brewing" product diff --git a/features/admin/product/managing_products/viewing_non_translatable_attributes.feature b/features/admin/product/managing_products/viewing_non_translatable_attributes.feature index 5a5387fcb9..9324fdfe33 100644 --- a/features/admin/product/managing_products/viewing_non_translatable_attributes.feature +++ b/features/admin/product/managing_products/viewing_non_translatable_attributes.feature @@ -10,7 +10,7 @@ Feature: Viewing product's non translatable attributes on edit page And this product has non-translatable percent attribute "crit chance" with value 10% And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Viewing product's attributes defined in different locales When I modify the "Iron Pickaxe" product And I should see non-translatable attribute "crit chance" with value 10% diff --git a/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature b/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature index d17de228b8..fa0cda88d6 100644 --- a/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature +++ b/features/admin/product/viewing_price_history/seeing_price_history_after_creating_product_variant.feature @@ -8,7 +8,7 @@ Feature: Seeing the correct catalog price history after creating a product varia Given the store operates on a single channel in "United States" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing historical product variant prices after the product variant has been created without any promotion applied Given the store has a "Wyborowa Vodka" configurable product When I want to create a new variant of this product @@ -20,7 +20,7 @@ Feature: Seeing the correct catalog price history after creating a product varia Then I should see a single log entry in the catalog price history And there should be a log entry with the "$20.00" selling price, "$25.00" original price and datetime of the price change - @api @ui + @api @todo @ui Scenario: Seeing historical product variant prices after the product variant has been created without original price and any promotion applied Given the store has a "Wyborowa Vodka" configurable product When I want to create a new variant of this product @@ -31,7 +31,7 @@ Feature: Seeing the correct catalog price history after creating a product varia Then I should see a single log entry in the catalog price history And there should be a log entry with the "$20.00" selling price, no original price and datetime of the price change - @api @ui + @api @todo @ui Scenario: Seeing historical product variant prices after the product variant has been created with catalog promotions applied Given the store has a "Wyborowa Vodka" configurable product And there is a catalog promotion "Christmas sale" that reduces price by "50%" and applies on "Wyborowa Vodka" product diff --git a/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature b/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature index 132773200f..c670c22dce 100644 --- a/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature +++ b/features/admin/product/viewing_price_history/seeing_price_history_after_editing_product_variant.feature @@ -9,7 +9,7 @@ Feature: Seeing the correct catalog price history after editing a product varian And the store has a product "Wyborowa Vodka" priced at "$40.00" in "United States" channel And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing historical product variant prices after the product variant has been edited When I want to modify the "Wyborowa Vodka" product variant And I change its price to "$42.00" for "United States" channel diff --git a/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature b/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature index a13185f909..707c012530 100644 --- a/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature +++ b/features/admin/product/viewing_price_history/seeing_price_history_of_simple_product_after_changes_to_catalog_promotions.feature @@ -13,7 +13,7 @@ Feature: Seeing the price history of a simple product after changes to catalog p And it reduces price by "90%" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing the catalog price history of a simple product Given the "Winter sale" catalog promotion is enabled When I disable "Winter sale" catalog promotion @@ -23,7 +23,7 @@ Feature: Seeing the price history of a simple product after changes to catalog p And there should be a log entry on the 2nd position with the "$10.00" selling price, "$100.00" original price and datetime of the price change And there should be a log entry on the 3rd position with the "$100.00" selling price, no original price and datetime of the price change - @api @ui + @api @todo @ui Scenario: Seeing the catalog price history of a simple product with a price different than an original price Given "Wyborowa Vodka" variant is originally priced at "$120.00" in "United States" channel And the "Winter sale" catalog promotion is enabled diff --git a/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature b/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature index 16c52b3320..877f446400 100644 --- a/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature +++ b/features/admin/product/viewing_product_in_admin_panel/accesing_product_edit_page_from_show_page.feature @@ -12,13 +12,13 @@ Feature: Accessing to product edit page from show page And I am logged in as an administrator And I am browsing products - @ui @no-api + @todo @ui @no-api Scenario: Accessing to product edit page from product show page When I access the "Iron Shield" product And I go to edit page Then I should be on "Iron shield" product edit page - @ui @no-api + @todo @ui @no-api Scenario: Accessing to variant edit page from product show page When I access the "Iron Shield" product And I go to edit page of "Iron shield - very big" variant diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature index af103dfa62..8f323cf4e7 100644 --- a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature +++ b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_for_a_simple_product.feature @@ -15,7 +15,7 @@ Feature: Seeing applied catalog promotions details for a simple product And I am logged in as an administrator And I am browsing products - @ui @no-api + @todo @ui @no-api Scenario: Seeing applied catalog promotion details on a simple product When I access "Ursus C-355" product Then this product price should be decreased by catalog promotion "Company bankruptcy sale" in "United States" channel diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature index 8994cca64e..89afc6c773 100644 --- a/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature +++ b/features/admin/product/viewing_product_in_admin_panel/viewing_applied_catalog_promotions_details_within_variant.feature @@ -22,7 +22,7 @@ Feature: Seeing applied catalog promotions details within variant And I am logged in as an administrator And I am browsing products - @ui @no-api + @todo @ui @no-api Scenario: Seeing applied catalog promotion details within variant When I access "Wyborowa Vodka" product Then "Wyborowa Vodka Exquisite" variant price should be decreased by catalog promotion "Winter sale" in "United States" channel diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature index e8844bf412..6fcc443a88 100644 --- a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature +++ b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_product_with_variants.feature @@ -17,13 +17,13 @@ Feature: Viewing details of a product with variants And I am logged in as an administrator And I am browsing products - @ui @no-api + @todo @ui @no-api Scenario: Viewing a configurable product When I access the "Iron Shield" product Then I should see product show page with variants And I should see product name "Iron Shield" - @ui @api + @todo @ui @api Scenario: Viewing taxonomies Given the store classifies its products as "Shield" and "Equipment" And the product "Iron Shield" has a main taxon "Equipment" @@ -32,32 +32,32 @@ Feature: Viewing details of a product with variants Then I should see main taxon is "Equipment" And I should see product taxon "Shield" - @ui @api + @todo @ui @api Scenario: Viewing options When I access the "Iron Shield" product Then I should see option "Shield size" - @ui @api + @todo @ui @api Scenario: Viewing variants When I access the "Iron Shield" product Then I should see 2 variants And I should see the "Iron Shield - very big" variant And I should see the "Iron Shield - very small" variant - @ui @no-api + @todo @ui @no-api Scenario: Viewing variants' details When I access the "Iron Shield" product Then I should see 2 variants And I should see "Iron Shield - very big" variant with code "123456789-xl", priced "$25.00" and current stock 5 and in "United States" channel And I should see "Iron Shield - very small" variant with code "123456789-xs", priced "$15.00" and current stock 12 and in "United States" channel - @ui @javascript @api + @todo @ui @javascript @api Scenario: Viewing media Given the "Iron Shield" product has an image "mugs.jpg" with "main" type When I access the "Iron Shield" product Then I should see an image related to this product - @ui @api + @todo @ui @api Scenario: Viewing more details Given the product "Iron Shield" has the slug "iron-shield" And the description of product "Iron Shield" is "Shield created by dwarf" @@ -70,14 +70,14 @@ Feature: Viewing details of a product with variants And I should see product's meta keywords is "shield" And I should see product's short description is "good shield" - @ui @api + @todo @ui @api Scenario: Viewing association types Given the store has a "Glass shield" product And the product "Iron Shield" has an association "Similar" with product "Glass shield" When I access the "Iron Shield" product Then I should see product association type "Similar" - @ui @no-api + @todo @ui @no-api Scenario: Viewing associations Given the store has a "Glass shield" product And the product "Iron Shield" has an association "Similar" with product "Glass shield" diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature index 71de4aff4a..fc4bbcdf8a 100644 --- a/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature +++ b/features/admin/product/viewing_product_in_admin_panel/viewing_details_of_simple_product.feature @@ -11,21 +11,21 @@ Feature: Viewing details of a simple product And I am logged in as an administrator And I am browsing products - @ui @no-api + @todo @ui @no-api Scenario: Viewing a simple product show page When I access the "Iron Shield" product Then I should see product show page without variants And I should see product name "Iron Shield" And I should see product breadcrumb "Iron Shield" - @ui @no-api + @todo @ui @no-api Scenario: Viewing pricing block Given the product "Iron Shield" has original price "$25.00" When I access the "Iron Shield" product Then I should see price "$20.00" for channel "United States" And I should see original price "$25.00" for channel "United States" - @ui @no-api + @todo @ui @no-api Scenario: Viewing price block without channel enable Given this product is unavailable in "United States" channel When I access the "Iron Shield" product @@ -33,7 +33,7 @@ Feature: Viewing details of a simple product And I should see the product in neither channel And I should not see price for channel "United States" - @ui @no-api + @todo @ui @no-api Scenario: Viewing details block Given the store has a tax category "No tax" with a code "nt" And product's "Iron Shield" code is "123456789" @@ -45,7 +45,7 @@ Feature: Viewing details of a simple product And I should see 4 as a current stock of this product And I should see product's tax category is "No tax" - @ui @no-api + @todo @ui @no-api Scenario: Viewing taxonomy block Given this product belongs to "Shield" And the product "Iron Shield" has a main taxon "Equipment" @@ -53,7 +53,7 @@ Feature: Viewing details of a simple product Then I should see main taxon is "Equipment" And I should see product taxon "Shield" - @ui @no-api + @todo @ui @no-api Scenario: Viewing shipping block Given the store has "Over sized" and "Standard" shipping category And the product "Iron Shield" has height "10.0", width "15.0", depth "20.0", weight "25.0" @@ -65,13 +65,13 @@ Feature: Viewing details of a simple product And I should see product's depth is 20 And I should see product's weight is 25 - @ui @javascript @api + @todo @ui @javascript @api Scenario: Viewing media block Given the "Iron Shield" product has an image "mugs.jpg" with "main" type When I access the "Iron Shield" product Then I should see an image related to this product - @ui @no-api + @todo @ui @no-api Scenario: Viewing "more details" block Given the product "Iron Shield" has the slug "iron-shield" And the description of product "Iron Shield" is "Shield created by dwarf" @@ -84,7 +84,7 @@ Feature: Viewing details of a simple product And I should see product's meta keywords is "shield" And I should see product's short description is "good shield" - @ui @no-api + @todo @ui @no-api Scenario: Viewing associations block Given the store has "Similar" and "Dwarf equipment" product association types And the store has a "Glass Shield" product diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature index ebff161863..74264d3138 100644 --- a/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature +++ b/features/admin/product/viewing_product_in_admin_panel/viewing_non_translatable_attributes_admin.feature @@ -14,7 +14,7 @@ Feature: Viewing product's non translatable attributes And I am logged in as an administrator And I am browsing products - @ui @api + @todo @ui @api Scenario: Viewing product's non translatable attributes along with default ones When I access the "Iron Pickaxe" product Then I should see non-translatable attribute "crit chance" with value 10% diff --git a/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature b/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature index 7d00084b0a..7d072f76f0 100644 --- a/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature +++ b/features/admin/product/viewing_product_in_admin_panel/viewing_product_attributes_in_different_locales.feature @@ -15,7 +15,7 @@ Feature: Viewing product's attributes in different locales And I am logged in as an administrator And I am browsing products - @ui @api + @todo @ui @api Scenario: Viewing product's attributes defined in different locales When I access the "Iron Shield" product Then I should see attribute "material" with value "oak wood" in "English (United States)" locale diff --git a/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature b/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature index b22fab3432..ff90ba9abe 100644 --- a/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature +++ b/features/admin/promotion/managing_catalog_promotions/adding_catalog_promotion_with_fixed_discount_where_amount_is_decimal_number_with_comma.feature @@ -8,7 +8,7 @@ Feature: Adding a new catalog promotion with fixed discount where amount is a de Given the store operates on a single channel in "United States" And I am logged in as an administrator - @ui @no-api @javascript + @ui @no-api @mink:chromedriver Scenario: Adding a new catalog promotion with fixed discount and amount with comma When I want to create a new catalog promotion And I specify its code as "winter_sale" diff --git a/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature b/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature index 5123815443..9660945f2d 100644 --- a/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature +++ b/features/admin/promotion/managing_catalog_promotions/browsing_variants_affected_by_catalog_promotions.feature @@ -15,27 +15,27 @@ Feature: Browsing variants affected by catalog promotions And this product has "Sylius T-Shirt" variant priced at "$15.00" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing product variants affected by a catalog promotion applied on variants Given there is a catalog promotion "PHP T-Shirt promotion" that reduces price by "50%" and applies on "PHP T-Shirt" variant When I browse variants affected by catalog promotion "PHP T-Shirt promotion" Then there should be 1 product variant on the list And it should be the "PHP T-Shirt" product variant - @ui @api + @todo @ui @api Scenario: Browsing product variants affected by a catalog promotion applied on products Given there is a catalog promotion "T-Shirt promotion" that reduces price by "20%" and applies on "T-Shirt" product When I browse variants affected by catalog promotion "T-Shirt promotion" Then there should be 2 product variants on the list And it should be "PHP T-Shirt" and "Sylius T-Shirt" product variants - @ui @api + @todo @ui @api Scenario: Browsing product variants affected by a catalog promotion applied on taxons Given there is a catalog promotion "Clothes promotion" that reduces price by "10%" and applies on "Clothes" taxon When I browse variants affected by catalog promotion "Clothes promotion" Then there should be 3 product variants on the list - @ui @api + @todo @ui @api Scenario: Browsing product variants affected by a catalog promotion when its scope overlaps with an exclusive promotion Given there is a catalog promotion "T-Shirt promotion" that reduces price by "20%" and applies on "T-Shirt" product And there is an exclusive catalog promotion "Sylius T-Shirt promotion" with priority 100 that reduces price by "30%" and applies on "Sylius T-Shirt" variant @@ -43,7 +43,7 @@ Feature: Browsing variants affected by catalog promotions Then there should be 1 product variant on the list And it should be the "PHP T-Shirt" product variant - @ui @no-api + @todo @ui @no-api Scenario: Accessing the product details page through affected product variants list Given there is a catalog promotion "PHP T-Shirt promotion" that reduces price by "50%" and applies on "PHP T-Shirt" variant When I browse variants affected by catalog promotion "PHP T-Shirt promotion" diff --git a/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature index 970e040b28..2a5a0b4e07 100644 --- a/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature +++ b/features/admin/promotion/managing_catalog_promotions/creating_catalog_promotion.feature @@ -140,8 +140,8 @@ Feature: Creating a catalog promotion Then the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$9.45" with 3 promotions And the visitor should see that the "Kotlin T-Shirt" variant is discounted from "$40.00" to "$30.00" with "Winter sale" promotion - @ui @javascript - Scenario: Adding a new catalog promotion of default type with one action + @ui @mink:chromedriver @no-api + Scenario: Adding a new catalog promotion with one scope and one action When I want to create a new catalog promotion And I add a new catalog promotion scope And I add a new catalog promotion action diff --git a/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature index a5b4845c36..7d992feae4 100644 --- a/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature +++ b/features/admin/promotion/managing_catalog_promotions/editing_catalog_promotion.feature @@ -50,14 +50,20 @@ Feature: Editing catalog promotion @api @ui @mink:chromedriver Scenario: Editing catalog promotion variant scope - When I edit "Christmas sale" catalog promotion to be applied on "Kotlin T-Shirt" variant + When I want to modify a catalog promotion "Christmas sale" + And I remove "PHP T-Shirt" variant from its scope + And I add "Kotlin T-Shirt" variant to its scope + And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should be applied on "Kotlin T-Shirt" variant And this catalog promotion should not be applied on "PHP T-Shirt" variant @api @ui @mink:chromedriver Scenario: Editing catalog promotion taxon scope - When I edit "Christmas sale" catalog promotion to be applied on "Clothes" taxon + When I want to modify a catalog promotion "Christmas sale" + And I remove its last scope + And I add scope that applies on "Clothes" taxon + And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should be applied on "Clothes" taxon And this catalog promotion should not be applied on "Kotlin T-Shirt" variant @@ -65,20 +71,28 @@ Feature: Editing catalog promotion @api @ui @mink:chromedriver Scenario: Editing catalog promotion product scope - When I edit "Christmas sale" catalog promotion to be applied on "T-Shirt" product + When I want to modify a catalog promotion "Christmas sale" + And I remove its last scope + And I add scope that applies on "T-Shirt" product + And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should be applied on "T-Shirt" product And this catalog promotion should not be applied on "PHP T-Shirt" variant @api @ui Scenario: Editing catalog promotion action - When I edit "Christmas sale" catalog promotion to have "40%" discount + When I want to modify a catalog promotion "Christmas sale" + And I edit its action so that it reduces price by "40%" + And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should have "40.00%" percentage discount - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Editing catalog promotion action to be a fixed discount - When I edit "Christmas sale" catalog promotion to have "$10.00" of fixed discount in the "United States" channel + When I want to modify a catalog promotion "Christmas sale" + When I remove its last action + And I add action that gives "$10.00" of fixed discount in the "United States" channel + And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should have "$10.00" of fixed discount in the "United States" channel @@ -101,7 +115,8 @@ Feature: Editing catalog promotion Scenario: Receiving error message after not filling price for all channels Given the store operates on another channel named "Poland" When I want to modify a catalog promotion "Christmas sale" - And I edit it to have "$10.00" of fixed discount in the "United States" channel + When I remove its last action + And I add action that gives "$10.00" of fixed discount in the "United States" channel And I make it available in channel "Poland" And I save my changes Then I should be notified that not all channels are filled @@ -113,7 +128,7 @@ Feature: Editing catalog promotion And I save my changes Then I should be notified that the percentage amount should be a number and cannot be empty - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Editing catalog promotion action to be a percentage discount and not filling amount Given there is a catalog promotion "Winter sale" that reduces price by fixed "$10.00" in the "United States" channel and applies on "T-Shirt" product When I want to modify a catalog promotion "Christmas sale" @@ -121,9 +136,10 @@ Feature: Editing catalog promotion And I save my changes Then I should be notified that the percentage amount should be a number and cannot be empty - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Editing catalog promotion action to be a fixed discount and not filling amount - When I want to modify a catalog promotion "Christmas sale" + Given there is a catalog promotion "Winter sale" that reduces price by fixed "$10.00" in the "United States" channel and applies on "T-Shirt" product + When I want to modify a catalog promotion "Winter sale" And I edit it to have empty amount of fixed discount in the "United States" channel And I save my changes - Then I should be notified that the fixed amount should be a number and cannot be empty + Then I should be notified that the fixed amount cannot be empty diff --git a/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature index 5f9ce689aa..35b5707765 100644 --- a/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature +++ b/features/admin/promotion/managing_catalog_promotions/seeing_correct_percantage_discounts_while_editing_catalog_promotion.feature @@ -17,16 +17,18 @@ Feature: Seeing correct percentage discounts while editing catalog promotion And it is enabled And I am logged in as an administrator - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Seeing the accurate percentage amount after editing the catalog promotion including the value up to one decimal place - When I edit "Christmas sale" catalog promotion to have "2.5%" discount + When I want to modify a catalog promotion "Christmas sale" + And I edit its action so that it reduces price by "2.5%" And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should have "2.50%" percentage discount - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Seeing the accurate percentage amount after editing the catalog promotion including the value up to two decimal places - When I edit "Christmas sale" catalog promotion to have "2.56%" discount + When I want to modify a catalog promotion "Christmas sale" + And I edit its action so that it reduces price by "2.56%" And I save my changes Then I should be notified that it has been successfully edited And this catalog promotion should have "2.56%" percentage discount diff --git a/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature b/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature index 7f9da33f13..2dd0589aaf 100644 --- a/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature +++ b/features/admin/promotion/managing_catalog_promotions/toggling_catalog_promotion.feature @@ -8,6 +8,7 @@ Feature: Toggling catalog promotion Given the store operates on a single channel in "United States" And the store has a "T-Shirt" configurable product And this product has "PHP T-Shirt" variant priced at "$20.00" + And this product has "PHPers T-Shirt" variant priced at "$25.00" And there is a catalog promotion "Christmas sale" that reduces price by "30%" and applies on "PHP T-Shirt" variant And I am logged in as an administrator diff --git a/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature b/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature index efb5a228cb..7cb7751da4 100644 --- a/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature +++ b/features/admin/promotion/managing_catalog_promotions/validating_catalog_promotion_creation.feature @@ -44,7 +44,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that catalog promotion with this code already exists And there should still be only one catalog promotion with code "sale" - @api + @api @no-ui Scenario: Trying to create a catalog promotion with invalid type of scope When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -56,7 +56,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that type of scope is invalid And there should be an empty list of catalog promotions - @api + @api @no-ui Scenario: Trying to create a catalog promotion with scope with invalid configuration When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -68,7 +68,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that scope configuration is invalid And there should be an empty list of catalog promotions - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to create a catalog promotion with not configured for variants scope When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -80,7 +80,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that at least 1 variant is required And there should be an empty list of catalog promotions - @api + @api @no-ui Scenario: Trying to create a catalog promotion with invalid type of action When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -144,10 +144,10 @@ Feature: Validating a catalog promotion creation And I add scope that applies on variants "PHP T-Shirt" variant and "Kotlin T-Shirt" variant And I add fixed discount action without amount configured for the "United States" channel And I try to add it - Then I should be notified that the fixed amount should be a number and cannot be empty + Then I should be notified that the fixed amount cannot be empty And there should be an empty list of catalog promotions - @api + @api @ui @mink:chromedriver Scenario: Trying to create a catalog promotion with wrong value of fixed discount action When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -158,10 +158,10 @@ Feature: Validating a catalog promotion creation And I add scope that applies on variants "PHP T-Shirt" variant and "Kotlin T-Shirt" variant And I add invalid fixed discount action with non number in amount for the "United States" channel And I try to add it - Then I should be notified that the fixed amount should be a number and cannot be empty + Then I should be notified that the fixed amount should be a number And there should be an empty list of catalog promotions - @api + @api @no-ui Scenario: Trying to create a catalog promotion with fixed discount action with invalid channel When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -176,7 +176,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that at least one of the provided channel codes does not exist And there should be an empty list of catalog promotions - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to create a catalog promotion with taxon type without taxons When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -188,7 +188,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that I must add at least one taxon And there should be an empty list of catalog promotions - @api + @api @no-ui Scenario: Trying to create a catalog promotion with taxon type with invalid taxons When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -200,7 +200,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that I can add only existing taxon And there should be an empty list of catalog promotions - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to create a catalog promotion with product type without products When I want to create a new catalog promotion And I specify its code as "winter_sale" @@ -212,7 +212,7 @@ Feature: Validating a catalog promotion creation Then I should be notified that I must add at least one product And there should be an empty list of catalog promotions - @api + @api @no-ui Scenario: Trying to create a catalog promotion with product type with invalid products When I want to create a new catalog promotion And I specify its code as "winter_sale" diff --git a/features/admin/promotion/managing_coupons/adding_coupon.feature b/features/admin/promotion/managing_coupons/adding_coupon.feature index 5f7c5ece9b..772eb1d6e6 100644 --- a/features/admin/promotion/managing_coupons/adding_coupon.feature +++ b/features/admin/promotion/managing_coupons/adding_coupon.feature @@ -10,7 +10,7 @@ Feature: Adding a new coupon And it is coupon based promotion And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new coupon When I want to create a new coupon for this promotion And I specify its code as "SANTA2016" diff --git a/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature b/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature index b5a84c2ae0..8232afd110 100644 --- a/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature +++ b/features/admin/promotion/managing_coupons/being_unable_to_generate_too_many_coupons_with_prefix_and_suffix.feature @@ -14,7 +14,7 @@ Feature: Being unable to generate too many coupons with prefix and suffix And it is coupon based promotion And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Being unable to generate too many coupons with prefix Given I have generated 8 coupons for this promotion with code length 1 and prefix "CHRISTMAS_" When I want to generate new coupons for this promotion @@ -25,7 +25,7 @@ Feature: Being unable to generate too many coupons with prefix and suffix Then I should be notified that generating 2 coupons with code length equal to 1 is not possible And there should still be 8 coupons related to this promotion - @api @ui + @api @todo @ui Scenario: Being unable to generate too many coupons with suffix Given I have generated 8 coupons for this promotion with code length 1 and suffix "_CHRISTMAS" When I want to generate new coupons for this promotion @@ -36,7 +36,7 @@ Feature: Being unable to generate too many coupons with prefix and suffix Then I should be notified that generating 2 coupons with code length equal to 1 is not possible And there should still be 8 coupons related to this promotion - @api @ui + @api @todo @ui Scenario: Being unable to generate too many coupons with prefix and suffix Given I have generated 8 coupons for this promotion with code length 1, prefix "CHRISTMAS_" and suffix "_SALE" When I want to generate new coupons for this promotion diff --git a/features/admin/promotion/managing_coupons/browsing_coupons.feature b/features/admin/promotion/managing_coupons/browsing_coupons.feature index e514a73c6b..8fd48cc773 100644 --- a/features/admin/promotion/managing_coupons/browsing_coupons.feature +++ b/features/admin/promotion/managing_coupons/browsing_coupons.feature @@ -9,7 +9,7 @@ Feature: Browsing promotion coupons And the store has promotion "Christmas sale" with coupon "SANTA2016" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing coupons of a promotion When I want to view all coupons of this promotion And there should be 1 coupon related to this promotion diff --git a/features/admin/promotion/managing_coupons/coupon_generate_validation.feature b/features/admin/promotion/managing_coupons/coupon_generate_validation.feature index 55c4b06ba1..f36e2758ae 100644 --- a/features/admin/promotion/managing_coupons/coupon_generate_validation.feature +++ b/features/admin/promotion/managing_coupons/coupon_generate_validation.feature @@ -10,7 +10,7 @@ Feature: Coupon generate instruction validation And it is coupon based promotion And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Trying to generate new coupons without specifying their amount When I want to generate new coupons for this promotion And I do not specify its amount @@ -21,7 +21,7 @@ Feature: Coupon generate instruction validation Then I should be notified that generate amount is required And there should be 0 coupon related to this promotion - @api @ui + @api @todo @ui Scenario: Trying to generate new coupons without specifying their code length When I want to generate new coupons for this promotion And I do not specify their code length @@ -32,7 +32,7 @@ Feature: Coupon generate instruction validation Then I should be notified that generate code length is required And there should be 0 coupon related to this promotion - @api @ui + @api @todo @ui Scenario: Trying to generate new coupons with code length impossible to generate When I want to generate new coupons for this promotion And I specify their code length as 50 @@ -43,7 +43,7 @@ Feature: Coupon generate instruction validation Then I should be notified that generate code length is out of range And there should be 0 coupon related to this promotion - @api @ui + @api @todo @ui Scenario: Trying to generate new coupons with amount and code length impossible to generate When I want to generate new coupons for this promotion And I specify their code length as 1 diff --git a/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature b/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature index 9331d10ee5..b3215b5736 100644 --- a/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature +++ b/features/admin/promotion/managing_coupons/coupon_unique_code_validation.feature @@ -9,7 +9,7 @@ Feature: Coupon unique code validation And the store has promotion "Christmas sale" with coupon "SANTA2016" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Trying to add coupon with taken code When I want to create a new coupon for this promotion And I specify its code as "SANTA2016" diff --git a/features/admin/promotion/managing_coupons/coupon_validation.feature b/features/admin/promotion/managing_coupons/coupon_validation.feature index cefc1334d1..170bc3cf1f 100644 --- a/features/admin/promotion/managing_coupons/coupon_validation.feature +++ b/features/admin/promotion/managing_coupons/coupon_validation.feature @@ -10,7 +10,7 @@ Feature: Coupon validation And it is coupon based promotion And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new coupon without specifying its code When I want to create a new coupon for this promotion And I do not specify its code @@ -21,7 +21,7 @@ Feature: Coupon validation Then I should be notified that code is required And there should be 0 coupons related to this promotion - @ui @api + @todo @ui @api Scenario: Trying to add a new coupon with a too long code When I want to create a new coupon for this promotion And I limit its usage to 30 times @@ -31,7 +31,7 @@ Feature: Coupon validation And I try to add it Then I should be notified that code is too long - @ui @api + @todo @ui @api Scenario: Trying to add a new coupon with usage limit below one When I want to create a new coupon for this promotion And I specify its code as "SANTA2016" @@ -42,7 +42,7 @@ Feature: Coupon validation Then I should be notified that coupon usage limit must be at least one And there should be 0 coupons related to this promotion - @ui @api + @todo @ui @api Scenario: Trying to add a new coupon with per customer usage limit below one When I want to create a new coupon for this promotion And I specify its code as "SANTA2016" diff --git a/features/admin/promotion/managing_coupons/deleting_coupon.feature b/features/admin/promotion/managing_coupons/deleting_coupon.feature index f54dd31f2c..4d675de437 100644 --- a/features/admin/promotion/managing_coupons/deleting_coupon.feature +++ b/features/admin/promotion/managing_coupons/deleting_coupon.feature @@ -9,7 +9,7 @@ Feature: Deleting a coupon And the store has promotion "Christmas sale" with coupon "SANTA2016" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted coupon should disappear from the registry When I delete "SANTA2016" coupon related to this promotion Then I should be notified that it has been successfully deleted diff --git a/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature b/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature index dee4e09b77..571d71b495 100644 --- a/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature +++ b/features/admin/promotion/managing_coupons/deleting_multiple_coupons.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple coupons And this promotion has "SANTA1", "SANTA2" and "SANTA3" coupons And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple coupons at once When I browse coupons of this promotion And I check the "SANTA1" coupon diff --git a/features/admin/promotion/managing_coupons/editing_coupon.feature b/features/admin/promotion/managing_coupons/editing_coupon.feature index c1e4afe187..e498c2c702 100644 --- a/features/admin/promotion/managing_coupons/editing_coupon.feature +++ b/features/admin/promotion/managing_coupons/editing_coupon.feature @@ -9,7 +9,7 @@ Feature: Editing promotion coupon And the store has promotion "Christmas sale" with coupon "SANTA2016" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Changing coupon expires date When I want to modify the "SANTA2016" coupon for this promotion And I change its expiration date to "21.05.2019" @@ -17,7 +17,7 @@ Feature: Editing promotion coupon Then I should be notified that it has been successfully edited And this coupon should be valid until "21.05.2019" - @ui @api + @todo @ui @api Scenario: Changing coupons usage limit When I want to modify the "SANTA2016" coupon for this promotion And I change its usage limit to 50 @@ -25,7 +25,7 @@ Feature: Editing promotion coupon Then I should be notified that it has been successfully edited And this coupon should have 50 usage limit - @ui @api + @todo @ui @api Scenario: Changing coupons per customer usage limit When I want to modify the "SANTA2016" coupon for this promotion And I change its per customer usage limit to 20 @@ -33,7 +33,7 @@ Feature: Editing promotion coupon Then I should be notified that it has been successfully edited And this coupon should have 20 per customer usage limit - @ui @api + @todo @ui @api Scenario: Changing whether it can be reused from cancelled orders When I want to modify the "SANTA2016" coupon for this promotion And I make it not reusable from cancelled orders @@ -41,7 +41,7 @@ Feature: Editing promotion coupon Then I should be notified that it has been successfully edited And this coupon should not be reusable from cancelled orders - @ui @api + @todo @ui @api Scenario: Being unable to change code of promotion coupon When I want to modify the "SANTA2016" coupon for this promotion Then I should not be able to edit its code diff --git a/features/admin/promotion/managing_coupons/generating_coupon.feature b/features/admin/promotion/managing_coupons/generating_coupon.feature index 5fa2812afa..dbacc815fc 100644 --- a/features/admin/promotion/managing_coupons/generating_coupon.feature +++ b/features/admin/promotion/managing_coupons/generating_coupon.feature @@ -10,7 +10,7 @@ Feature: Generating new coupons And it is coupon based promotion And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Generating a new coupons When I want to generate new coupons for this promotion And I choose the amount of 5 coupons to be generated @@ -21,7 +21,7 @@ Feature: Generating new coupons Then I should be notified that they have been successfully generated And there should be 5 coupons related to this promotion - @api @ui + @api @todo @ui Scenario: Generating new coupons without expiration date When I want to generate new coupons for this promotion And I choose the amount of 5 coupons to be generated @@ -31,7 +31,7 @@ Feature: Generating new coupons Then I should be notified that they have been successfully generated And there should be 5 coupons related to this promotion - @api @ui + @api @todo @ui Scenario: Generating new coupons with a large long code length value When I want to generate new coupons for this promotion And I choose the amount of 10 coupons to be generated diff --git a/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature b/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature index 1918ed8e36..2e471f496e 100644 --- a/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature +++ b/features/admin/promotion/managing_coupons/generating_coupon_with_prefix_and_suffix.feature @@ -10,7 +10,7 @@ Feature: Generating new coupons with prefix and suffix And it is coupon based promotion And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Generating new coupons with prefix When I want to generate new coupons for this promotion And I choose the amount of 5 coupons to be generated @@ -21,7 +21,7 @@ Feature: Generating new coupons with prefix and suffix And there should be 5 coupons related to this promotion And all of the coupon codes should be prefixed with "CHRISTMAS_" - @api @ui + @api @todo @ui Scenario: Generating new coupons with suffix When I want to generate new coupons for this promotion And I choose the amount of 5 coupons to be generated @@ -32,7 +32,7 @@ Feature: Generating new coupons with prefix and suffix And there should be 5 coupons related to this promotion And all of the coupon codes should be suffixed with "_CHRISTMAS" - @api @ui + @api @todo @ui Scenario: Generating new coupons with prefix and suffix When I want to generate new coupons for this promotion And I choose the amount of 5 coupons to be generated diff --git a/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature b/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature index d475ad68a9..3e69e883cf 100644 --- a/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature +++ b/features/admin/promotion/managing_coupons/preventing_deletion_of_coupons_in_use.feature @@ -15,7 +15,7 @@ Feature: Not being able to delete a coupon which is in use And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Being unable to delete a used coupon When I try to delete "SANTA2016" coupon related to this promotion Then I should be notified that it is in use and cannot be deleted diff --git a/features/admin/promotion/managing_coupons/sorting_coupons.feature b/features/admin/promotion/managing_coupons/sorting_coupons.feature index e1eb8ba9d7..fb58cdd941 100644 --- a/features/admin/promotion/managing_coupons/sorting_coupons.feature +++ b/features/admin/promotion/managing_coupons/sorting_coupons.feature @@ -19,69 +19,69 @@ Feature: Sorting listed coupons And this coupon expires on "20-02-2023" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Coupons are sorted by descending number of uses by default When I want to view all coupons of this promotion Then I should see 3 coupons on the list And the first coupon should have code "Y" - @ui @api + @todo @ui @api Scenario: Changing the number of uses sorting order to ascending Given I am browsing coupons of this promotion When I sort coupons by ascending number of uses Then I should see 3 coupons on the list And the first coupon should have code "X" - @ui @api + @todo @ui @api Scenario: Sorting coupons by code in descending order Given I am browsing coupons of this promotion When I sort coupons by descending code Then I should see 3 coupons on the list And the first coupon should have code "Z" - @ui @api + @todo @ui @api Scenario: Sorting coupons by code in ascending order Given I am browsing coupons of this promotion When I sort coupons by ascending code Then I should see 3 coupons on the list And the first coupon should have code "X" - @ui @no-postgres @api + @todo @ui @no-postgres @api Scenario: Sorting coupons by usage limit in descending order Given I am browsing coupons of this promotion When I sort coupons by descending usage limit Then I should see 3 coupons on the list And the first coupon should have code "X" - @ui @no-postgres @api + @todo @ui @no-postgres @api Scenario: Sorting coupons by usage limit in ascending order Given I am browsing coupons of this promotion When I sort coupons by ascending usage limit Then I should see 3 coupons on the list And the first coupon should have code "Z" - @ui @no-postgres @api + @todo @ui @no-postgres @api Scenario: Sorting coupons by usage limit per customer in descending order Given I am browsing coupons of this promotion When I sort coupons by descending usage limit per customer Then I should see 3 coupons on the list And the first coupon should have code "X" - @ui @no-postgres @api + @todo @ui @no-postgres @api Scenario: Sorting coupons by usage limit per customer in ascending order Given I am browsing coupons of this promotion When I sort coupons by ascending usage limit per customer Then I should see 3 coupons on the list And the first coupon should have code "Y" - @ui @no-postgres @api + @todo @ui @no-postgres @api Scenario: Sorting coupons by expiration date in descending order Given I am browsing coupons of this promotion When I sort coupons by descending expiration date Then I should see 3 coupons on the list And the first coupon should have code "Z" - @ui @no-postgres @api + @todo @ui @no-postgres @api Scenario: Sorting coupons by expiration date in ascending order Given I am browsing coupons of this promotion When I sort coupons by ascending expiration date diff --git a/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature b/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature index 64bd6d998f..0ef74c8253 100644 --- a/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature +++ b/features/admin/promotion/managing_promotions/accessing_the_coupons_management_from_the_promotion_page.feature @@ -10,13 +10,13 @@ Feature: Accessing the coupons management from the promotion page And it is a coupon based promotion And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Being able to manage promotion's coupons When I modify a "Christmas sale" promotion And I want to manage this promotion coupons Then I should be on this promotion's coupons management page - @ui @no-api + @todo @ui @no-api Scenario: Add new promotion and not being able to manage promotion's coupons When I create a new promotion And I specify its code as "FULL_METAL_PROMOTION" diff --git a/features/admin/promotion/managing_promotions/adding_promotion.feature b/features/admin/promotion/managing_promotions/adding_promotion.feature index 8ca1c91bea..ef27e4019b 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion.feature @@ -75,3 +75,11 @@ Feature: Adding a new promotion And I add it Then I should be notified that it has been successfully created And the "Full metal promotion" promotion should not applies to discounted items + + @ui @mink:chromedriver @no-api + Scenario: Seeing rule and action configuration forms + When I want to create a new promotion + And I add a new rule + And I add a new action + Then I should see the rule configuration form + And I should see the action configuration form diff --git a/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature b/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature index 65ae9d7bc3..12bcaed068 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion_in_different_languages.feature @@ -9,7 +9,7 @@ Feature: Adding promotion in different languages And that channel allows to shop using "English (United States)" and "Polish (Poland)" locales And I am logged in as an administrator - @api @ui @javascript + @api @ui Scenario: Adding a promotion with a label in a different language When I want to create a new promotion And I specify its code as "FULL_METAL_PROMOTION" diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature index 9aed8f5060..b129b3048d 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion_with_action.feature @@ -8,7 +8,7 @@ Feature: Adding a new promotion with action Given the store operates on a single channel in "United States" And I am logged in as an administrator - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a new promotion with fixed discount When I want to create a new promotion And I specify its code as "10_for_all_products" @@ -18,7 +18,7 @@ Feature: Adding a new promotion with action Then I should be notified that it has been successfully created And the "$10.00 for all products!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with item percentage discount When I want to create a new promotion And I specify its code as "promotion_for_all_product_items" diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature index da704d642d..3620dcd099 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion_with_action_in_different_channels.feature @@ -17,5 +17,4 @@ Feature: Adding a new promotion with action configured in different channels And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel And it is also configured with amount of "£16.00" for "Web-GB" channel And I add it - Then I should be notified that it has been successfully created - And the "Item fixed discount for all products!" promotion should appear in the registry + Then the "Item fixed discount for all products!" promotion should be successfully created diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature index 62e7e2388c..185fd9859d 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion_with_filter.feature @@ -16,10 +16,9 @@ Feature: Adding promotion with filter And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel And I specify that on "United States" channel this action should be applied to items with price greater than "$10.00" And I add it - Then I should be notified that it has been successfully created - And the "$10 discount for all products over $10!" promotion should appear in the registry + Then the "$10 discount for all products over $10!" promotion should be successfully created - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with item fixed discount only for products between 10 and 100 When I want to create a new promotion And I specify its code as "10_for_all_products_over_10" @@ -30,31 +29,31 @@ Feature: Adding promotion with filter Then I should be notified that it has been successfully created And the "$10 discount for (almost) all products!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with fixed discount for all t-shirts Given the store classifies its products as "T-Shirts" and "Mugs" When I want to create a new promotion And I specify its code as "10_for_all_t_shirts" And I name it "$10 discount for all T-Shirts!" And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel - And I specify that this action should be applied to items from "T-Shirts" category + And I specify that this action should be applied to items from "T-Shirts" category for "United States" channel And I add it Then I should be notified that it has been successfully created And the "$10 discount for all T-Shirts!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with fixed discount for PHP T-Shirt Given the store has a product "PHP T-Shirt" priced at "$100.00" When I want to create a new promotion And I specify its code as "10_for_php_t_shirt" And I name it "$10 discount for PHP T-Shirts!" And I add the "Item fixed discount" action configured with amount of "$10.00" for "United States" channel - And I specify that this action should be applied to the "PHP T-Shirt" product + And I specify that this action should be applied to the "PHP T-Shirt" product for "United States" channel And I add it Then I should be notified that it has been successfully created And the "$10 discount for PHP T-Shirts!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with item percentage discount only for products over 10 When I want to create a new promotion And I specify its code as "10_for_all_products_over_10" @@ -65,7 +64,7 @@ Feature: Adding promotion with filter Then I should be notified that it has been successfully created And the "$10 discount for all products over $10!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with item percentage discount only for products between 10 and 100 When I want to create a new promotion And I specify its code as "10_for_all_products_over_10" @@ -73,29 +72,29 @@ Feature: Adding promotion with filter And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel And I specify that on "United States" channel this action should be applied to items with price between "$10.00" and "$100.00" And I add it - Then I should be notified that it has been successfully created + Then the "$10 discount for (almost) all products!" promotion should be successfully created And the "$10 discount for (almost) all products!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with 10% percentage discount for all t-shirts Given the store classifies its products as "T-Shirts" and "Mugs" When I want to create a new promotion And I specify its code as "10_for_all_t_shirts" And I name it "$10 discount for all T-Shirts!" And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel - And I specify that this action should be applied to items from "T-Shirts" category + And I specify that this action should be applied to items from "T-Shirts" category for "United States" channel And I add it Then I should be notified that it has been successfully created And the "$10 discount for all T-Shirts!" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with 10% percentage discount for PHP T-Shirt Given the store has a product "PHP T-Shirt" priced at "$100.00" When I want to create a new promotion And I specify its code as "10_for_php_t_shirt" And I name it "10% discount for PHP T-Shirts!" And I add the "Item percentage discount" action configured with a percentage value of "10%" for "United States" channel - And I specify that this action should be applied to the "PHP T-Shirt" product + And I specify that this action should be applied to the "PHP T-Shirt" product for "United States" channel And I add it Then I should be notified that it has been successfully created And the "10% discount for PHP T-Shirts!" promotion should appear in the registry diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature index 8014a1e5f1..1fc72625c0 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion_with_rule.feature @@ -9,17 +9,17 @@ Feature: Adding a new promotion with rule And the store classifies its products as "T-Shirts" and "Mugs" And I am logged in as an administrator - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a new promotion with taxon rule When I want to create a new promotion And I specify its code as "HOLIDAY_SALE" And I name it "Holiday sale" And I add the "Has at least one from taxons" rule configured with "T-Shirts" taxon and "Mugs" taxon And I add it - Then I should be notified that it has been successfully created + Then the "Holiday sale" promotion should be successfully created And the "Holiday sale" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a new promotion with total price of items from taxon rule When I want to create a new promotion And I specify its code as "100_MUGS_PROMOTION" @@ -29,7 +29,7 @@ Feature: Adding a new promotion with rule Then I should be notified that it has been successfully created And the "100 Mugs promotion" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a new promotion with contains product rule Given the store has a product "PHP T-Shirt" priced at "$100.00" When I want to create a new promotion @@ -40,7 +40,7 @@ Feature: Adding a new promotion with rule Then I should be notified that it has been successfully created And the "PHP T-Shirt promotion" promotion should appear in the registry - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a new group based promotion Given the store has a customer group "Wholesale" When I want to create a new promotion @@ -50,11 +50,3 @@ Feature: Adding a new promotion with rule And I add it Then I should be notified that it has been successfully created And the "Wholesale promotion" promotion should appear in the registry - - @ui @javascript @no-api - Scenario: Adding a new promotion of default type with one action - When I want to create a new promotion - And I add a new rule - And I add a new action - Then I should see the rule configuration form - And I should see the action configuration form diff --git a/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature b/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature index 5c572c6738..35be86e7e1 100644 --- a/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature +++ b/features/admin/promotion/managing_promotions/adding_promotion_with_rule_in_different_channels.feature @@ -10,11 +10,10 @@ Feature: Adding a new promotion with rule configured in different channels And I am logged in as an administrator @api @ui @mink:chromedriver - Scenario: Adding a new promotion with total price of items + Scenario: Adding a new promotion with total price of items from taxon rule When I want to create a new promotion And I specify its code as "100_IN_EVERY_CURRENCY" And I name it "100 in every currency" And I add the "Item total" rule configured with "€100.00" amount for "United States" channel and "£100.00" amount for "Web-GB" channel And I add it - Then I should be notified that it has been successfully created - And the "100 in every currency" promotion should appear in the registry + Then the "100 in every currency" promotion should be successfully created diff --git a/features/admin/promotion/managing_promotions/browsing_promotions.feature b/features/admin/promotion/managing_promotions/browsing_promotions.feature index 22161f20b5..b4a3b7dcce 100644 --- a/features/admin/promotion/managing_promotions/browsing_promotions.feature +++ b/features/admin/promotion/managing_promotions/browsing_promotions.feature @@ -9,13 +9,13 @@ Feature: Browsing promotions And there is a promotion "Basic promotion" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Browsing promotions When I want to browse promotions Then I should see a single promotion in the list And the "Basic promotion" promotion should exist in the registry - @api @ui + @api @todo @ui Scenario: Browsing manage button for coupon based promotion Given the store has promotion "Christmas sale" with coupon "Santa's gift" When I want to browse promotions diff --git a/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature b/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature index b3f907f5ff..63a61df75d 100644 --- a/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature +++ b/features/admin/promotion/managing_promotions/deleting_multiple_promotions.feature @@ -11,7 +11,7 @@ Feature: Deleting multiple promotions And there is also a promotion "Easter sale" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple promotions at once When I browse promotions And I check the "Christmas sale" promotion diff --git a/features/admin/promotion/managing_promotions/editing_promotion.feature b/features/admin/promotion/managing_promotions/editing_promotion.feature index 2eabd044bd..749665eb86 100644 --- a/features/admin/promotion/managing_promotions/editing_promotion.feature +++ b/features/admin/promotion/managing_promotions/editing_promotion.feature @@ -62,7 +62,7 @@ Feature: Editing promotion Then I should be able to modify a "Christmas sale" promotion @ui @no-api - Scenario: Remove priority from existing promotion + Scenario: Removing priority from existing promotion When I want to modify a "Christmas sale" promotion And I remove its priority And I save my changes @@ -76,3 +76,13 @@ Feature: Editing promotion And I save my changes Then I should be notified that it has been successfully edited And the "Christmas sale" promotion should have priority 1 + + @ui @mink:chromedriver + Scenario: Removing rule and action from existing promotion + Given the promotion gives "$10.00" discount to every order with quantity at least 1 + When I want to modify a "Holiday sale" promotion + And I remove its last rule + And I remove its last action + And I save my changes + Then I should not see the rule configuration form + And I should not see the action configuration form diff --git a/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature b/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature index 7b8eb87ea4..61325a8c1e 100644 --- a/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature +++ b/features/admin/promotion/managing_promotions/filtering_promotions_by_coupon_code.feature @@ -11,7 +11,7 @@ Feature: Filtering promotions by coupon code And the store has promotion "Christmas sale" with coupon "MAGIC" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Filtering promotions by coupon code When I want to browse promotions And I filter promotions by coupon code equal "MAGIC" diff --git a/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature b/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature index 7454f04ec8..76ca873d81 100644 --- a/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature +++ b/features/admin/promotion/managing_promotions/prevent_from_removing_products_that_are_used_in_promotion_rules.feature @@ -9,7 +9,7 @@ Feature: Preventing from removing products that are used in promotion rules And the store has "Mug" and "Cup" products And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Being prevented from removing a product that is in use by a promotion rule Given there is a promotion "Christmas sale" with "Contains product" rule with product "Mug" When I try to delete the "Mug" product diff --git a/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature b/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature index 842506bcfb..4032b439ba 100644 --- a/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature +++ b/features/admin/promotion/managing_promotions/prevent_from_removing_taxons_that_are_used_in_promotion_rules.feature @@ -9,7 +9,7 @@ Feature: Preventing from removing taxons that are used in promotion rules And the store has "Mugs" taxonomy And I am logged in as an administrator - @api @ui @mink:chromedriver + @api @todo @ui @mink:chromedriver Scenario: Being prevented from removing taxon that is in use by a promotion rule Given there is a promotion "Christmas sale" with "Total price of items from taxon" rule configured with "Mugs" taxon and $100 amount for "United States" channel When I try to delete taxon named "Mugs" diff --git a/features/admin/promotion/managing_promotions/promotion_validation.feature b/features/admin/promotion/managing_promotions/promotion_validation.feature index 3ffb1944aa..5e66860c10 100644 --- a/features/admin/promotion/managing_promotions/promotion_validation.feature +++ b/features/admin/promotion/managing_promotions/promotion_validation.feature @@ -69,7 +69,7 @@ Feature: Promotion validation And I try to save my changes Then I should be notified that promotion cannot end before it starts - @api @ui @mink:chromedriver + @api @ui Scenario: Adding a promotion with label exceeding 255 characters Given there is a promotion "Christmas sale" When I want to modify this promotion @@ -77,7 +77,7 @@ Feature: Promotion validation And I try to save my changes Then I should be notified that promotion label in "Polish (Poland)" locale is too long - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to add a new promotion without specifying a order percentage discount When I want to create a new promotion And I specify its code as "christmas_sale" @@ -87,7 +87,7 @@ Feature: Promotion validation Then I should be notified that this value should not be blank And promotion with name "Christmas sale" should not be added - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to add a new promotion without specifying an item percentage discount When I want to create a new promotion And I specify its code as "christmas_sale" @@ -97,7 +97,7 @@ Feature: Promotion validation Then I should be notified that this value should not be blank And promotion with name "Christmas sale" should not be added - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to add a new promotion with a wrong order percentage discount When I want to create a new promotion And I specify its code as "christmas_sale" @@ -107,7 +107,7 @@ Feature: Promotion validation Then I should be notified that a percentage discount value must be between 0% and 100% And promotion with name "Christmas sale" should not be added - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Trying to add a new promotion with a wrong item percentage discount When I want to create a new promotion And I specify its code as "christmas_sale" diff --git a/features/admin/promotion/managing_promotions/promotions_filter_validation.feature b/features/admin/promotion/managing_promotions/promotions_filter_validation.feature index 6fe1bd3044..0fecb83828 100644 --- a/features/admin/promotion/managing_promotions/promotions_filter_validation.feature +++ b/features/admin/promotion/managing_promotions/promotions_filter_validation.feature @@ -8,7 +8,7 @@ Feature: Promotion filters validation Given the store operates on a single channel in "United States" And I am logged in as an administrator - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with wrong minimum price on price range filter When I want to create a new promotion And I specify its code as "10_for_all_products_over_10" @@ -19,7 +19,7 @@ Feature: Promotion filters validation Then I should be notified that a minimum value should be a numeric value And promotion with name "$10 discount for all products over $10!" should not be added - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Adding a promotion with wrong maximum price on price range filter When I want to create a new promotion And I specify its code as "10_for_all_products_over_10" diff --git a/features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature b/features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature similarity index 100% rename from features/admin/promotion/managing_promotions/seeing_correct_percantage_discounts_while_editing_promotion_with_action_and_decimal_places.feature rename to features/admin/promotion/managing_promotions/seeing_correct_percentage_discounts_while_editing_promotion_with_action_and_decimal_places.feature diff --git a/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature b/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature index 9cb2b9be00..c81c925823 100644 --- a/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature +++ b/features/admin/promotion/managing_promotions/seeing_errors_in_promotion_channel_based_configuration.feature @@ -11,7 +11,7 @@ Feature: Seeing errors in promotion channel based configuration And there is a promotion "Holiday promotion" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Seeing the number of errors per channel in order fixed discount Given this promotion gives "$10.00" discount to every order in the "Web" channel and "$5.00" discount to every order in the "Mobile" channel When I want to modify a "Holiday promotion" promotion @@ -19,7 +19,7 @@ Feature: Seeing errors in promotion channel based configuration And I try to save my changes And I should see that the action for "Mobile" channel has 1 validation error - @ui @no-api + @todo @ui @no-api Scenario: Seeing the number of errors per channel in product fixed discount Given this promotion gives "$2.00" off on every product in the "Web" channel and "$3.00" off in the "Mobile" channel When I want to modify a "Holiday promotion" promotion @@ -27,7 +27,7 @@ Feature: Seeing errors in promotion channel based configuration And I try to save my changes And I should see that the action for "Mobile" channel has 1 validation error - @ui @no-api + @todo @ui @no-api Scenario: Seeing the number of errors per channel in product percentage discount Given this promotion gives "5%" off on every product in the "Web" channel and "10%" off in the "Mobile" channel When I want to modify a "Holiday promotion" promotion @@ -35,7 +35,7 @@ Feature: Seeing errors in promotion channel based configuration And I try to save my changes And I should see that the action for "Mobile" channel has 1 validation error - @ui @no-api + @todo @ui @no-api Scenario: Seeing the number of errors per channel with rule based on items' total Given this promotion gives "$10.00" discount to every order in the "Web" channel and "$5.00" discount to every order in the "Mobile" channel And this promotion only applies to orders with a total of at least "$100.00" for "Web" channel and "$50.00" for "Mobile" channel diff --git a/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature b/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature index cd44a2e403..bdf1a06f33 100644 --- a/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature +++ b/features/admin/promotion/managing_promotions/sorting_promotions_by_priority.feature @@ -11,21 +11,21 @@ Feature: Sorting listed promotions by priority And there is a promotion "Pugs For Everyone" with priority 0 And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Promotions are sorted by priority in descending order by default When I want to browse promotions Then I should see 3 promotions on the list And the first promotion on the list should have name "Honour Harambe" And the last promotion on the list should have name "Pugs For Everyone" - @api @ui + @api @todo @ui Scenario: Promotion's default priority is 0 which puts it at the bottom of the list Given there is a promotion "Flying Pigs" When I want to browse promotions Then I should see 4 promotions on the list And the last promotion on the list should have name "Flying Pigs" - @api @ui + @api @todo @ui Scenario: Promotion added with priority -1 is set at the top of the list Given there is a promotion "Flying Pigs" with priority -1 When I want to browse promotions diff --git a/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature b/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature index fd49bd1d71..200d22eb25 100644 --- a/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature +++ b/features/admin/promotion/removing_catalog_promotions/removing_catalog_promotions.feature @@ -13,7 +13,7 @@ Feature: Removing a catalog promotions And there is a catalog promotion "Winter Sale" that reduces price by "30%" and applies on "Clothes" taxon And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Removing an expired catalog promotion Given it is "2022-08-22" now And the catalog promotion "Winter Sale" operates between "2021-12-20" and "2021-12-30" @@ -22,14 +22,14 @@ Feature: Removing a catalog promotions And there should be an empty list of catalog promotions And "PHP T-Shirt" variant should not be discounted - @api @ui + @api @todo @ui Scenario: Removing an active catalog promotion without any time limits When I request the removal of "Winter Sale" catalog promotion Then I should be notified that the removal operation has started successfully And there should be an empty list of catalog promotions And "PHP T-Shirt" variant should not be discounted - @api @ui + @api @todo @ui Scenario: Removing an active catalog promotion in the time range Given it is "2022-12-15" now And the catalog promotion "Winter Sale" operates between "2022-12-01" and "2022-12-30" @@ -38,7 +38,7 @@ Feature: Removing a catalog promotions And there should be an empty list of catalog promotions And "PHP T-Shirt" variant should not be discounted - @api @ui + @api @todo @ui Scenario: Removing a scheduled catalog promotion Given it is "2022-08-22" now And the catalog promotion "Winter Sale" operates between "2022-12-01" and "2023-02-28" diff --git a/features/admin/promotion/tracking_usage/checking_promotion_usage.feature b/features/admin/promotion/tracking_usage/checking_promotion_usage.feature index 3cfae047d5..65f8c0c115 100644 --- a/features/admin/promotion/tracking_usage/checking_promotion_usage.feature +++ b/features/admin/promotion/tracking_usage/checking_promotion_usage.feature @@ -16,7 +16,7 @@ Feature: Checking a promotion usage after placing an order And there is a promotion "Christmas promotion" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing item fixed discount promotion usage unchanged after order placement Given the promotion gives "$10.00" off on every product with minimum price at "$50.00" And the promotion gives another "$5.00" off on every product classified as "T-Shirts" @@ -26,7 +26,7 @@ Feature: Checking a promotion usage after placing an order When I browse promotions Then the promotion "Christmas promotion" should not be used - @api @ui + @api @todo @ui Scenario: Seeing item fixed discount promotion usage increased after order placement Given the promotion gives "$10.00" off on every product with minimum price at "$50.00" And the promotion gives another "$5.00" off on every product classified as "Mugs" @@ -36,7 +36,7 @@ Feature: Checking a promotion usage after placing an order When I browse promotions Then the promotion "Christmas promotion" should be used 1 time - @api @ui + @api @todo @ui Scenario: Seeing shipping percentage discount promotion usage unchanged after order placement Given the promotion gives "100%" discount on shipping to every order And there is a customer "john.doe@gmail.com" that placed an order "#00000022" diff --git a/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature b/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature index e20c381ff9..13f33e97f9 100644 --- a/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature +++ b/features/admin/promotion/tracking_usage/decreasing_promotion_coupon_usage_after_cancelling_order.feature @@ -12,7 +12,7 @@ Feature: Decreasing a promotion coupon usage after cancelling an order And the store has promotion "Christmas sale" with coupon "SANTA2016" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing promotion coupon usage decreased after order cancellation Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon @@ -21,7 +21,7 @@ Feature: Decreasing a promotion coupon usage after cancelling an order When I browse all coupons of "Christmas sale" promotion Then "SANTA2016" coupon should be used 0 times - @api @ui + @api @todo @ui Scenario: Seeing promotion coupon usage decreased to 1 after second order cancellation Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon diff --git a/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature b/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature index 5b739c684c..784e5f2878 100644 --- a/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature +++ b/features/admin/promotion/tracking_usage/decreasing_promotion_usage_after_cancelling_order.feature @@ -12,7 +12,7 @@ Feature: Decreasing a promotion usage after cancelling an order And there is a promotion "Limited promotion" limited to 5 usages And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing promotion usage decreased after order cancellation Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" And the customer bought a single "PHP T-Shirt" diff --git a/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature b/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature index bea00a7c3f..74c1fe682c 100644 --- a/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature +++ b/features/admin/promotion/tracking_usage/increasing_promotion_coupon_usage_after_placing_order.feature @@ -12,7 +12,7 @@ Feature: Increasing a promotion coupon usage after placing an order And the store has promotion "Christmas sale" with coupon "SANTA2016" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing promotion coupon usage increased after order placement Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon @@ -20,7 +20,7 @@ Feature: Increasing a promotion coupon usage after placing an order When I browse all coupons of "Christmas sale" promotion Then "SANTA2016" coupon should be used 1 time - @api @ui + @api @todo @ui Scenario: Seeing promotion coupon usage increased correctly after few orders placement Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" And the customer bought a single "PHP T-Shirt" using "SANTA2016" coupon diff --git a/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature b/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature index 412a1c5e74..d77fe5d378 100644 --- a/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature +++ b/features/admin/promotion/tracking_usage/increasing_promotion_usage_after_placing_order.feature @@ -13,7 +13,7 @@ Feature: Increasing a promotion usage after placing an order And it gives "$10.00" discount to every order And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Seeing promotion usage increased after order placement Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" And the customer bought a single "PHP T-Shirt" diff --git a/features/admin/redirecting_on_login_after_being_logout.feature b/features/admin/redirecting_on_login_after_being_logout.feature index f370b73f79..baa80ac119 100644 --- a/features/admin/redirecting_on_login_after_being_logout.feature +++ b/features/admin/redirecting_on_login_after_being_logout.feature @@ -8,7 +8,7 @@ Feature: Redirecting on login page Given the store operates on a single channel in "United States" And I have been logged out from administration - @ui @no-api + @todo @ui @no-api Scenario: Redirecting on login page after being logout When I try to open administration dashboard Then I should be on login page diff --git a/features/admin/resetting_password.feature b/features/admin/resetting_password.feature index d92e04bad8..b20a5c5dfd 100644 --- a/features/admin/resetting_password.feature +++ b/features/admin/resetting_password.feature @@ -8,7 +8,7 @@ Feature: Resetting an administrator's password Given the store operates on a single channel in "United States" And there is an administrator "sylius@example.com" identified by "sylius" - @email @api @ui + @email @api @todo @ui Scenario: Sending an administrator's password reset request When I want to reset password And I specify email as "sylius@example.com" @@ -16,7 +16,7 @@ Feature: Resetting an administrator's password Then I should be notified that email with reset instruction has been sent And an email with instructions on how to reset the administrator's password should be sent to "sylius@example.com" - @email @api @ui + @email @api @todo @ui Scenario: Notifying about sending reset instructions even when an admin with email does not exist When I want to reset password And I specify email as "does-not-exist@example.com" @@ -24,7 +24,7 @@ Feature: Resetting an administrator's password Then I should be notified that email with reset instruction has been sent But "does-not-exist@example.com" should receive no emails - @ui @api + @todo @ui @api Scenario: Changing my administrator's password Given I have already received a resetting password email When I follow the instructions to reset my password @@ -34,7 +34,7 @@ Feature: Resetting an administrator's password Then I should be notified that my password has been successfully changed And I should be able to log in as "sylius@example.com" authenticated by "newp@ssw0rd" password - @ui @api + @todo @ui @api Scenario: Trying to change my administrator's password twice without sending a new password reset request Given I have already received an administrator's password resetting email When I follow the instructions to reset my password @@ -53,7 +53,7 @@ Feature: Resetting an administrator's password And I reset it Then I should be notified that the password reset token has expired - @ui @no-api + @todo @ui @no-api Scenario: Trying to change my administrator's password using an expired reset token Given I have already received an administrator's password resetting email But my password reset token has already expired diff --git a/features/admin/resetting_password_validation.feature b/features/admin/resetting_password_validation.feature index 244d1944fe..9ed42a66f6 100644 --- a/features/admin/resetting_password_validation.feature +++ b/features/admin/resetting_password_validation.feature @@ -7,14 +7,14 @@ Feature: Resetting an administrator's password validation Background: Given there is an administrator "sylius@example.com" identified by "sylius" - @ui @api + @todo @ui @api Scenario: Trying to reset my administrator's password without specifying email When I want to reset password And I do not specify an email And I try to reset it Then I should be notified that the email is required - @ui @api + @todo @ui @api Scenario: Trying to reset my administrator's password with an empty value Given I have already received an administrator's password resetting email When I follow the instructions to reset my password @@ -23,14 +23,14 @@ Feature: Resetting an administrator's password validation And I try to reset it Then I should be notified that the new password is required - @ui @api + @todo @ui @api Scenario: Trying to reset my administrator's password with an invalid email When I want to reset password And I specify email as "sylius@examplecom" And I try to reset it Then I should be notified that the email is not valid - @ui @api + @todo @ui @api Scenario: Trying to reset my administrator's password with a wrong confirmation password Given I have already received an administrator's password resetting email When I follow the instructions to reset my password @@ -39,7 +39,7 @@ Feature: Resetting an administrator's password validation And I try to reset it Then I should be notified that the entered passwords do not match - @ui @api + @todo @ui @api Scenario: Trying to reset my administrator's password with a too short password Given I have already received an administrator's password resetting email When I follow the instructions to reset my password diff --git a/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature b/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature index a97ac4017f..2c9c676149 100644 --- a/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature +++ b/features/admin/securing_access_to_account_after_using_back_button_after_logging_out.feature @@ -8,7 +8,7 @@ Feature: Securing access to the administration panel after using the back button Given the store operates on a single channel in "United States" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Securing access to administration dashboard after using the back button after logging out When I am on the administration dashboard And I log out diff --git a/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature b/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature index 1e3067a39a..2f4ee99e11 100644 --- a/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature +++ b/features/admin/shipping/managing_shipments/accessing_shipments_order_from_shipment_index.feature @@ -15,7 +15,7 @@ Feature: Accessing shipment's order from the shipments index And the customer chose "UPS" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Accessing shipment's order from the shipment When I browse shipments And I move to the details of first shipment's order diff --git a/features/admin/shipping/managing_shipments/browsing_shipments.feature b/features/admin/shipping/managing_shipments/browsing_shipments.feature index 2e92aeb6b5..bd4f57f2f1 100644 --- a/features/admin/shipping/managing_shipments/browsing_shipments.feature +++ b/features/admin/shipping/managing_shipments/browsing_shipments.feature @@ -21,20 +21,20 @@ Feature: Browsing shipments And the customer chose "UPS" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing shipments and their states in one channel When I browse shipments Then I should see 2 shipments in the list And I should see the shipment of order "#00000001" as "Shipped" And I should see the shipment of order "#00000002" as "Ready" - @ui @api + @todo @ui @api Scenario: Shipments are sorted by newest as default When I browse shipments Then I should see shipment for the "#00000002" order as 1st in the list And I should see shipment for the "#00000001" order as 2nd in the list - @ui @api + @todo @ui @api Scenario: Not seeing shipments in cart state Given the customer "customer@example.com" added "Banana" product to the cart When I browse shipments diff --git a/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature b/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature index 91fe974e5f..a606678cc9 100644 --- a/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature +++ b/features/admin/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature @@ -27,7 +27,7 @@ Feature: Browsing shipments from multiple channels And the customer chose "FEDEX" shipping method with "Bank transfer" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing shipments and their states from multiple channels When I browse shipments And I should see 2 shipments in the list diff --git a/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature b/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature index 6c54dabca5..b50e56d276 100644 --- a/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature +++ b/features/admin/shipping/managing_shipments/filtering_shipments_by_channel.feature @@ -27,7 +27,7 @@ Feature: Filtering shipments by a channel And the customer chose "FEDEX" shipping method with "Bank transfer" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering shipments by channel on index When I browse shipments And I choose "United States" as a channel filter diff --git a/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature b/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature index 1f19221e6b..37e233ca4f 100644 --- a/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature +++ b/features/admin/shipping/managing_shipments/filtering_shipments_by_shipping_method.feature @@ -21,7 +21,7 @@ Feature: Filtering shipments by a shipping method And the customer chose "DHL" shipping method to "United States" with "Offline" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering shipments by a shipping method When I browse shipments And I choose "DHL" as a shipping method filter diff --git a/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature b/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature index cf0433040d..342a93f29b 100644 --- a/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature +++ b/features/admin/shipping/managing_shipments/filtering_shipments_by_state.feature @@ -20,7 +20,7 @@ Feature: Filtering shipments by state And the customer chose "UPS" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Filtering payments in state "Shipped" When I browse shipments And I choose "shipped" as a shipment state diff --git a/features/admin/shipping/managing_shipments/seeing_shipment_details.feature b/features/admin/shipping/managing_shipments/seeing_shipment_details.feature index 705dba90bc..969ab3abb9 100644 --- a/features/admin/shipping/managing_shipments/seeing_shipment_details.feature +++ b/features/admin/shipping/managing_shipments/seeing_shipment_details.feature @@ -16,7 +16,7 @@ Feature: Seeing basic information about shipment And the customer chose "UPS" shipping method with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Seeing basic information about shipment When I view the first shipment of the order "#00000001" Then I should see 2 "Apple" units in the list diff --git a/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature b/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature index 25f9a56f28..b60ecad13f 100644 --- a/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature +++ b/features/admin/shipping/managing_shipments/shipping_a_shipment_from_shipment_list.feature @@ -38,7 +38,7 @@ Feature: Shipping a shipment from shipment list Then I should see the shipment of order "#00000001" as "Shipped" And I should see the shipment of order "#00000001" shipped at "20-02-2020 10:30:05" - @api + @api @no-ui Scenario: Shipping a shipment that has been already shipped Given this order has already been shipped When I try to ship the shipment of order "#00000001" diff --git a/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature b/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature index cae33de4e5..24409c183d 100644 --- a/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature +++ b/features/admin/shipping/managing_shipping_categories/adding_shipping_category.feature @@ -8,7 +8,7 @@ Feature: Adding a new shipping category Given the store operates on a single channel in "United States" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new shipping category with detailed information When I want to create a new shipping category And I specify its code as "OVER_SIZED" diff --git a/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature b/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature index 6bfbd96de6..38eb1b29a0 100644 --- a/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature +++ b/features/admin/shipping/managing_shipping_categories/browsing_shipping_categories.feature @@ -9,7 +9,7 @@ Feature: Browsing shipping categories And the store has "Over sized" and "Standard" shipping category And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing defined shipping categories When I browse shipping categories Then I should see 2 shipping categories in the list diff --git a/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature b/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature index e4e8dddeec..0a9521d87b 100644 --- a/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature +++ b/features/admin/shipping/managing_shipping_categories/deleting_multiple_shipping_categories.feature @@ -9,7 +9,7 @@ Feature: Deleting multiple shipping categories And the store has "Big" and "Small" shipping category And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple shipping categories at once When I browse shipping categories And I check the "Big" shipping category diff --git a/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature b/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature index 4c65065dd2..c8492c60ae 100644 --- a/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature +++ b/features/admin/shipping/managing_shipping_categories/deleting_shipping_category.feature @@ -9,7 +9,7 @@ Feature: Deleting a shipping category And the store has "Standard" shipping category And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted shipping category should disappear from the registry When I delete shipping category "Standard" Then I should be notified that it has been successfully deleted diff --git a/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature b/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature index c888921c5e..7c75a3997b 100644 --- a/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature +++ b/features/admin/shipping/managing_shipping_categories/editing_shipping_category.feature @@ -9,12 +9,12 @@ Feature: Editing shipping method And the store has "Standard" shipping category And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Seeing disabled code field when editing shipping category When I modify a shipping category "Standard" Then I should not be able to edit its code - @ui @api + @todo @ui @api Scenario: Renaming the shipping category When I want to modify a shipping category "Standard" And I rename it to "Normal" diff --git a/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature b/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature index cbaccc74b1..aa22cc1993 100644 --- a/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature +++ b/features/admin/shipping/managing_shipping_categories/shipping_category_unique_code_validation.feature @@ -9,7 +9,7 @@ Feature: Shipping category unique code validation And the store has "Standard" shipping category identified by "STANDARD" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add shipping category with taken code When I want to create a new shipping category And I specify its code as "STANDARD" diff --git a/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature b/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature index 290bc70458..3c78452750 100644 --- a/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature +++ b/features/admin/shipping/managing_shipping_categories/shipping_category_validation.feature @@ -8,7 +8,7 @@ Feature: Shipping category validation Given the store operates on a single channel in "United States" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new shipping category without specifying its code When I want to create a new shipping category And I name it "Standard" @@ -17,7 +17,7 @@ Feature: Shipping category validation Then I should be notified that code is required And shipping category with name "Standard" should not be added - @ui @api + @todo @ui @api Scenario: Trying to add a new shipping category with a too long code When I want to create a new shipping category And I name it "Standard" @@ -25,7 +25,7 @@ Feature: Shipping category validation And I try to add it Then I should be notified that code is too long - @ui @api + @todo @ui @api Scenario: Trying to add a new shipping category without specifying its name When I want to create a new shipping category And I specify its code as "STANDARD" diff --git a/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature b/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature index 90eadb63ce..3b99c1a7b1 100644 --- a/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature +++ b/features/admin/shipping/managing_shipping_methods/adding_shipping_method.feature @@ -20,8 +20,7 @@ Feature: Adding a new shipping method And I choose "Flat rate per shipment" calculator And I specify its amount as 50 for "Web-US" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created @ui @mink:chromedriver @api Scenario: Adding a new shipping method with description and flat rate per shipment @@ -33,10 +32,9 @@ Feature: Adding a new shipping method And I choose "Flat rate per shipment" calculator And I specify its amount as 50 for "Web-US" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a new shipping method with flat rate per unit When I want to create a new shipping method And I specify its code as "FED_EX_CARRIER" @@ -45,10 +43,9 @@ Feature: Adding a new shipping method And I choose "Flat rate per unit" calculator And I specify its amount as 20 for "Web-US" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding a new shipping method for channel When I want to create a new shipping method And I specify its code as "FED_EX_CARRIER" @@ -59,8 +56,7 @@ Feature: Adding a new shipping method And I choose "Flat rate per unit" calculator And I specify its amount as 20 for "Web-US" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created And the shipping method "FedEx Carrier" should be available in channel "Web-US" @ui @mink:chromedriver @api @@ -74,5 +70,4 @@ Feature: Adding a new shipping method And I specify its amount as 50 for "Web-US" channel And I specify its amount as 40 for "Web-GB" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created diff --git a/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature b/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature index 3e6206533b..106eb980e3 100644 --- a/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature +++ b/features/admin/shipping/managing_shipping_methods/adding_shipping_method_with_rule.feature @@ -21,8 +21,7 @@ Feature: Adding a new shipping method with rule And I specify its amount as 50 for "Web-US" channel And I add the "Total weight greater than or equal" rule configured with "20" And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created @ui @mink:chromedriver @api Scenario: Adding a new shipping method with total weight less than or equal rule @@ -35,8 +34,7 @@ Feature: Adding a new shipping method with rule And I specify its amount as 50 for "Web-US" channel And I add the "Total weight less than or equal" rule configured with "20" And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created @ui @mink:chromedriver @api Scenario: Adding a new shipping method with order total greater than or equal rule @@ -49,8 +47,7 @@ Feature: Adding a new shipping method with rule And I specify its amount as 50 for "Web-US" channel And I add the "Items total greater than or equal" rule configured with $200 for "Web-US" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created @ui @mink:chromedriver @api Scenario: Adding a new shipping method with order total less than or equal rule @@ -63,5 +60,4 @@ Feature: Adding a new shipping method with rule And I specify its amount as 50 for "Web-US" channel And I add the "Items total less than or equal" rule configured with $200 for "Web-US" channel And I add it - Then I should be notified that it has been successfully created - And the shipping method "FedEx Carrier" should appear in the registry + Then the "FedEx Carrier" shipping method should be successfully created diff --git a/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature b/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature index fa633c8062..4d641f64e9 100644 --- a/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature +++ b/features/admin/shipping/managing_shipping_methods/archiving_shipping_methods.feature @@ -9,20 +9,20 @@ Feature: Archiving obsolete shipping methods And the store allows shipping with "UPS Carrier" and "FedEx Carrier" And I am logged in as an administrator - @ui @api + @ui @mink:chromedriver @api Scenario: Archiving a shipping method Given I am browsing shipping methods When I archive the "UPS Carrier" shipping method Then the only shipping method on the list should be "FedEx Carrier" - @ui @api + @ui @mink:chromedriver @api Scenario: Seeing only archived shipping methods Given the shipping method "UPS Carrier" is archival And I am browsing shipping methods When I filter archival shipping methods Then the only shipping method on the list should be "UPS Carrier" - @ui @api + @ui @mink:chromedriver @api Scenario: Restoring an archival shipping method Given the shipping method "UPS Carrier" is archival And I am browsing archival shipping methods diff --git a/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature b/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature index 2aa41a15dc..982c22b908 100644 --- a/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature +++ b/features/admin/shipping/managing_shipping_methods/deleting_multiple_shipping_methods.feature @@ -9,7 +9,7 @@ Feature: Deleting multiple shipping methods And the store allows shipping with "UPS", "FedEx" and "DHL" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple shipping methods at once When I browse shipping methods And I check the "UPS" shipping method diff --git a/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature b/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature index cb5f0d412d..36332fa307 100644 --- a/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature +++ b/features/admin/shipping/managing_shipping_methods/deleting_shipping_method.feature @@ -9,8 +9,9 @@ Feature: Deleting a shipping method And the store allows shipping with "UPS Ground" And I am logged in as an administrator - @ui @api + @ui @mink:chromedriver @api Scenario: Deleted shipping method should disappear from the registry - When I delete shipping method "UPS Ground" + When I browse shipping methods + And I delete shipping method "UPS Ground" Then I should be notified that it has been successfully deleted - Then this shipping method should no longer exist in the registry + And this shipping method should no longer exist in the registry diff --git a/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature b/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature index e432189829..2eb60a5303 100644 --- a/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature +++ b/features/admin/shipping/managing_shipping_methods/denying_access_to_shipping_methods_for_unauthorized_users.feature @@ -10,41 +10,41 @@ Feature: Denying access to shipping methods for unauthorized users And the store has a zone "United States" with code "US" And the store allows shipping with "UPS Carrier" identified by "UPS_CARRIER" - @api + @api @no-ui Scenario: Trying to add a new shipping method as a unauthorized user When I try to create a new shipping method with valid data And I try to add it Then I should be notified that my access has been denied - @api + @api @no-ui Scenario: Trying to rename the shipping method Given I try to modify a shipping method "UPS Carrier" When I rename it to "UPS Transport" in "English (United States)" And I try to save my changes Then I should be notified that my access has been denied - @api + @api @no-ui Scenario: Trying to browse shipping methods When I try to browse shipping methods Then I should be notified that my access has been denied - @api + @api @no-ui Scenario: Trying to show shipping method When I try to show "UPS Carrier" shipping method Then I should be notified that my access has been denied - @api + @api @no-ui Scenario: Trying to archive a shipping method When I try to archive the "UPS Carrier" shipping method Then I should be notified that my access has been denied - @api + @api @no-ui Scenario: Trying to restore a shipping method Given the shipping method "UPS Carrier" is archival When I try to restore the "UPS Carrier" shipping method Then I should be notified that my access has been denied - @api + @api @no-ui Scenario: Trying to delete shipping method When I try to delete shipping method "UPS Carrier" Then I should be notified that my access has been denied diff --git a/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature b/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature index afbbb00dd9..89b7b78693 100644 --- a/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature +++ b/features/admin/shipping/managing_shipping_methods/preventing_deletion_of_used_shipping_method.feature @@ -14,7 +14,7 @@ Feature: Prevent deletion of used shipping method And the customer chose "DHL Express" shipping method to "United States" with "Cash on Delivery" payment And I am logged in as an administrator - @ui @api + @ui @mink:chromedriver @api Scenario: Being unable to delete a shipping method which is in use When I try to delete shipping method "DHL Express" Then I should be notified that it is in use diff --git a/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature b/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature index ea4aef4c1f..5d0b70c13f 100644 --- a/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature +++ b/features/admin/shipping/managing_shipping_methods/seeing_errors_in_shipping_method_charges.feature @@ -11,7 +11,7 @@ Feature: Seeing errors in shipping method charges And the store has a zone "United States" with code "US" And I am logged in as an administrator - @ui @no-api + @ui @mink:chromedriver @no-api Scenario: Seeing the number of errors with per shipment charges Given the store has "FedEx Carrier" shipping method with "$20.00" fee per shipment for "Web" channel and "$15.00" for "Mobile" channel When I want to modify this shipping method @@ -19,7 +19,7 @@ Feature: Seeing errors in shipping method charges And I try to save my changes Then I should see that the shipping charges for "Mobile" channel has 1 validation error - @ui @no-api + @ui @mink:chromedriver @no-api Scenario: Seeing the number of errors with per unit charges Given the store has "FedEx Carrier" shipping method with "$20.00" fee per unit for "Web" channel and "$15.00" for "Mobile" channel When I want to modify this shipping method diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature index ac638f5396..7f3d93cf4a 100644 --- a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature +++ b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_shipment_validation.feature @@ -10,7 +10,7 @@ Feature: Shipping method flat rate per shipment calculator validation And the store has a zone "United States" with code "US" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Trying to add a new shipping method with flat rate per shipment calculator without specifying its amount When I want to create a new shipping method And I specify its code as "FED_EX_CARRIER" @@ -21,7 +21,7 @@ Feature: Shipping method flat rate per shipment calculator validation Then I should be notified that amount for "Web" channel should not be blank And shipping method with name "FedEx Carrier" should not be added - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Trying to add a new shipping method with flat rate per shipment calculator with charge below 0 When I want to create a new shipping method And I specify its code as "FED_EX_CARRIER" diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature index b5afb7ffa6..623d87b44b 100644 --- a/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature +++ b/features/admin/shipping/managing_shipping_methods/shipping_method_flat_rate_per_unit_validation.feature @@ -10,7 +10,7 @@ Feature: Shipping method flat rate per unit calculator validation And the store has a zone "United States" with code "US" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Trying to add a new shipping method with flat rate per unit calculator without specifying its amount When I want to create a new shipping method And I specify its code as "FED_EX_CARRIER" @@ -21,7 +21,7 @@ Feature: Shipping method flat rate per unit calculator validation Then I should be notified that amount for "Web" channel should not be blank And shipping method with name "FedEx Carrier" should not be added - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Trying to add a new shipping method with flat rate per unit calculator with charge below 0 When I want to create a new shipping method And I specify its code as "FED_EX_CARRIER" diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature index 43ef82d7cb..50c9e7eb41 100644 --- a/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature +++ b/features/admin/shipping/managing_shipping_methods/shipping_method_unique_code_validation.feature @@ -11,7 +11,7 @@ Feature: Shipping method unique code validation And the store allows shipping with "UPS Ground" identified by "UPS" And I am logged in as an administrator - @ui @api @javascript + @ui @api @mink:chromedriver Scenario: Trying to add shipping method with taken code When I want to create a new shipping method And I specify its code as "UPS" diff --git a/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature b/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature index 742161eb54..76b3b71192 100644 --- a/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature +++ b/features/admin/shipping/managing_shipping_methods/shipping_method_validation.feature @@ -10,7 +10,6 @@ Feature: Shipping method validation And the store is available in "English (United States)" And I am logged in as an administrator - @no-ui @api Scenario: Trying to add shipping method translation in unexisting locale When I want to create a new shipping method diff --git a/features/admin/signing_in_to_administration_panel.feature b/features/admin/signing_in_to_administration_panel.feature index 734035d780..cfe1914cba 100644 --- a/features/admin/signing_in_to_administration_panel.feature +++ b/features/admin/signing_in_to_administration_panel.feature @@ -9,7 +9,7 @@ Feature: Signing in to the administration panel And there is a user "ted@example.com" identified by "bear" And there is an administrator "admin@example.com" identified by "sylius" - @ui @api + @todo @ui @api Scenario: Sign in with email and password When I want to log in And I specify the username as "admin@example.com" @@ -17,7 +17,7 @@ Feature: Signing in to the administration panel And I log in Then I should be logged in - @ui @api + @todo @ui @api Scenario: Sign in with bad credentials When I want to log in And I specify the username as "admin@example.com" @@ -26,7 +26,7 @@ Feature: Signing in to the administration panel Then I should be notified about bad credentials And I should not be logged in - @ui @api + @todo @ui @api Scenario: Sign in using customer account When I want to log in And I specify the username as "ted@example.com" diff --git a/features/admin/statistics.feature b/features/admin/statistics.feature index 71100eb2ac..cb46c4ec04 100644 --- a/features/admin/statistics.feature +++ b/features/admin/statistics.feature @@ -12,7 +12,7 @@ Feature: Statistics And this product has "Red XL" variant priced at "$40.00" And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Seeing statistics for the current year and default channel when expectations are not specified Given it is "last day of December last year" now And 2 new customers have fulfilled 2 orders placed for total of "$1,000.00" @@ -26,7 +26,7 @@ Feature: Statistics And there should be total sales of "$7,000.58" And the average order value should be "$1,166.76" - @api @ui @javascript + @api @todo @ui @javascript Scenario: Seeing statistics for the previous year Given it is "first day of January last year" now And 3 new customers have fulfilled 2 orders placed for total of "$2,000.00" @@ -39,7 +39,7 @@ Feature: Statistics And there should be total sales of "$2,000.00" And the average order value should be "$1,000.00" - @ui @javascript @no-api + @ui @todo @javascript @no-api Scenario: Seeing statistics for the next year Given it is "first day of January last year" now And 3 new customers have fulfilled 2 orders placed for total of "$2,000.00" @@ -53,7 +53,7 @@ Feature: Statistics And there should be total sales of "$10,000.74" And the average order value should be "$1,428.68" - @api @ui @javascript + @api @todo @ui @javascript Scenario: Seeing statistics that include only fulfilled orders that were not cancelled Given 4 new customers have fulfilled 4 orders placed for total of "$5,241.00" And 2 more new customers have placed 2 orders for total of "$459.00" diff --git a/features/admin/statistics_per_channel.feature b/features/admin/statistics_per_channel.feature index 6544f3ccdd..e8ac73b000 100644 --- a/features/admin/statistics_per_channel.feature +++ b/features/admin/statistics_per_channel.feature @@ -13,7 +13,7 @@ Feature: Statistics for a specific channel And the store allows paying Offline And I am logged in as an administrator - @ui @no-api + @todo @ui @no-api Scenario: Seeing basic statistics for the first channel by default Given 3 new customers have fulfilled 4 orders placed for total of "$8,566.00" mostly "Onion" product And 2 more new customers have fulfilled 2 orders placed for total of "$459.00" mostly "Banana" product @@ -23,7 +23,7 @@ Feature: Statistics for a specific channel And there should be total sales of "$8,566.00" And the average order value should be "$2,141.50" - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Switching to the channel with only fulfilled orders Given 4 new customers have fulfilled 4 orders placed for total of "$5,241.00" mostly "Onion" product And 2 more new customers have fulfilled 2 orders placed for total of "$459.00" mostly "Banana" product @@ -35,7 +35,7 @@ Feature: Statistics for a specific channel And there should be total sales of "$459.00" And the average order value should be "$229.50" - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Switching to the channel with both fulfilled and placed orders Given 4 new customers have fulfilled 4 orders placed for total of "$5,241.00" mostly "Onion" product And 2 more new customers have fulfilled 2 orders placed for total of "$459.00" mostly "Banana" product @@ -47,14 +47,14 @@ Feature: Statistics for a specific channel And there should be total sales of "$5,241.00" And the average order value should be "$1,310.25" - @no-api @ui + @todo @no-api @ui Scenario: Seeing recent orders in a specific channel Given 3 new customers have placed 4 orders for total of "$8,566.00" mostly "Onion" product And 2 more new customers have placed 2 orders for total of "$459.00" mostly "Banana" product When I view statistics for "WEB-POLAND" channel Then I should see 4 new orders in the list - @no-api @ui + @todo @no-api @ui Scenario: Seeing recent orders in a specific channel Given 3 new customers have placed 4 orders for total of "$8,566.00" mostly "Onion" product And 2 more new customers have placed 2 orders for total of "$459.00" mostly "Banana" product diff --git a/features/admin/switching_admins_locale.feature b/features/admin/switching_admins_locale.feature index 8aae78290d..24fc884313 100644 --- a/features/admin/switching_admins_locale.feature +++ b/features/admin/switching_admins_locale.feature @@ -11,33 +11,33 @@ Feature: Switching locales on admin's panel And I am logged in as an administrator And I am using "English (United States)" locale for my panel - @ui + @todo @ui Scenario: Changing my preferred locale Given I am editing my details When I set my locale to "Spanish (Mexico)" Then I should be viewing the administration panel in "Spanish (Mexico)" - @ui + @todo @ui Scenario: Changing my preferred language to a locale that does not exist in the store Given the locale "French (France)" does not exist in the store And I am editing my details When I set my locale to "French (France)" Then I should be viewing the administration panel in "French (France)" - @ui + @todo @ui Scenario: Changing panel's locale doesn't change shop's locale Given I am editing my details When I set my locale to "Spanish (Mexico)" And I browse that channel Then I should still shop using the "English (United States)" locale - @ui + @todo @ui Scenario: Changing shop's locale has doesn't affect admin panel's locale Given I switched the shop's locale to "Spanish (Mexico)" When I open administration dashboard Then I should still be viewing the administration panel in "English (United States)" - @ui + @todo @ui Scenario: Locales are saved per each admin's preference Given I am using "Spanish (Mexico)" locale for my panel And there is an administrator "admin@example.com" identified by "sylius" diff --git a/features/admin/taxation/managing_tax_categories/adding_tax_category.feature b/features/admin/taxation/managing_tax_categories/adding_tax_category.feature index 023c2af286..51201fe72a 100644 --- a/features/admin/taxation/managing_tax_categories/adding_tax_category.feature +++ b/features/admin/taxation/managing_tax_categories/adding_tax_category.feature @@ -7,7 +7,7 @@ Feature: Adding a new tax category Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new tax category When I want to create a new tax category And I specify its code as "food_and_beverage" @@ -16,7 +16,7 @@ Feature: Adding a new tax category Then I should be notified that it has been successfully created And the tax category "Food and Beverage" should appear in the registry - @ui @api + @todo @ui @api Scenario: Adding a new tax category with a description When I want to create a new tax category And I specify its code as "food_and_beverage" diff --git a/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature b/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature index c1b6d5c71e..0a3ba694b1 100644 --- a/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature +++ b/features/admin/taxation/managing_tax_categories/deleting_multiple_tax_categories.feature @@ -8,7 +8,7 @@ Feature: Deleting multiple tax categories Given the store has tax categories "Alcohol", "Food" and "Books" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple tax categories at once When I browse tax categories And I check the "Alcohol" tax category diff --git a/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature b/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature index 5758a072df..74ff518fad 100644 --- a/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature +++ b/features/admin/taxation/managing_tax_categories/deleting_tax_category.feature @@ -8,7 +8,7 @@ Feature: Deleting a tax category Given the store has a tax category "Alcohol" with a code "alcohol" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleted tax category should disappear from the registry When I delete tax category "Alcohol" Then I should be notified that it has been successfully deleted diff --git a/features/admin/taxation/managing_tax_categories/editing_tax_category.feature b/features/admin/taxation/managing_tax_categories/editing_tax_category.feature index fa33d446b2..be7783824f 100644 --- a/features/admin/taxation/managing_tax_categories/editing_tax_category.feature +++ b/features/admin/taxation/managing_tax_categories/editing_tax_category.feature @@ -8,12 +8,12 @@ Feature: Editing tax category Given the store has a tax category "Alcohol" with a code "alcohol" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Inability of changing the code of an existing tax category When I want to modify a tax category "Alcohol" Then I should not be able to edit its code - @ui @api + @todo @ui @api Scenario: Renaming the tax category When I want to modify a tax category "Alcohol" And I rename it to "Food & Alcohol" diff --git a/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature b/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature index 295ba8483a..6537ef5066 100644 --- a/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature +++ b/features/admin/taxation/managing_tax_categories/tax_category_unique_code_validation.feature @@ -8,7 +8,7 @@ Feature: Tax category unique code validation Given the store has a tax category "Alcohol" with a code "alcohol" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add tax category with taken code When I want to create a new tax category And I name it "Food and Beverage" diff --git a/features/admin/taxation/managing_tax_categories/tax_category_validation.feature b/features/admin/taxation/managing_tax_categories/tax_category_validation.feature index 73724b627e..347c4b766b 100644 --- a/features/admin/taxation/managing_tax_categories/tax_category_validation.feature +++ b/features/admin/taxation/managing_tax_categories/tax_category_validation.feature @@ -7,7 +7,7 @@ Feature: Tax category validation Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new tax category without specifying its code When I want to create a new tax category And I name it "Food and Beverage" @@ -16,7 +16,7 @@ Feature: Tax category validation Then I should be notified that code is required And tax category with name "Food and Beverage" should not be added - @ui @api + @todo @ui @api Scenario: Trying to add a new tax category with a too long code When I want to create a new tax category And I name it "Food and Beverage" @@ -24,7 +24,7 @@ Feature: Tax category validation And I try to add it Then I should be notified that code is too long - @ui @api + @todo @ui @api Scenario: Trying to add a new tax category without specifying its name When I want to create a new tax category And I specify its code as "food_and_beverage" @@ -33,7 +33,7 @@ Feature: Tax category validation Then I should be notified that name is required And tax category with code "food_and_beverage" should not be added - @ui @api + @todo @ui @api Scenario: Trying to remove name from existing tax category Given the store has a tax category "Alcoholic Drinks" with a code "alcohol" When I want to modify this tax category diff --git a/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature b/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature index 85cc677755..ea08816fdd 100644 --- a/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature +++ b/features/admin/taxation/managing_tax_rates/adding_tax_rate.feature @@ -77,7 +77,7 @@ Feature: Adding a new tax rate Then I should be notified that it has been successfully created And the tax rate "United States Sales Tax" should appear in the registry - @api @ui @mink:chromedriver + @api @ui Scenario: Adding a new tax rate which will be included in product price When I want to create a new tax rate And I specify its code as "US_SALES_TAX" diff --git a/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature b/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature index 8cc35ebfe1..0f503ebd0c 100644 --- a/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature +++ b/features/admin/taxation/managing_tax_rates/deleting_multiple_tax_rates.feature @@ -11,7 +11,7 @@ Feature: Deleting multiple tax rates And the store has "High VAT" tax rate of 40% for "Food" for the rest of the world And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple tax rates at once When I browse tax rates And I check the "Low VAT" tax rate diff --git a/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature b/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature index 6408428459..7cddd29ef5 100644 --- a/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/adding_images_to_existing_taxon.feature @@ -35,7 +35,7 @@ Feature: Adding images to an existing taxon And this taxon should have an image with "banner" type And it should also have an image with "thumbnail" type - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Adding multiple images of the same type to an existing taxon When I want to modify the "T-Shirts" taxon And I attach the "t-shirts.jpg" image with "banner" type to this taxon diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon.feature b/features/admin/taxonomy/managing_taxons/adding_taxon.feature index 8c13291ac8..c2014adff5 100644 --- a/features/admin/taxonomy/managing_taxons/adding_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/adding_taxon.feature @@ -8,7 +8,7 @@ Feature: Adding a new taxon Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new taxon When I want to create a new taxon And I specify its code as "t-shirts" @@ -18,7 +18,7 @@ Feature: Adding a new taxon Then I should be notified that it has been successfully created And the "T-Shirts" taxon should appear in the registry - @ui @api + @todo @ui @api Scenario: Adding a new taxon with slug and description When I want to create a new taxon And I specify its code as "category" diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature b/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature index 6f968b64f5..2ad49f8310 100644 --- a/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature +++ b/features/admin/taxonomy/managing_taxons/adding_taxon_for_parent.feature @@ -9,7 +9,7 @@ Feature: Adding a new taxon for parent And the store has "Category" taxonomy And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new taxon for specific parent taxon When I want to create a new taxon for "Category" And I specify its code as "guns" diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature b/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature index 231859d48d..419393f0c9 100644 --- a/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature +++ b/features/admin/taxonomy/managing_taxons/adding_taxon_with_images.feature @@ -13,6 +13,7 @@ Feature: Adding a new taxon with images When I want to create a new taxon And I specify its code as "t-shirts" And I name it "T-Shirts" in "English (United States)" + And I set its slug to "t-shirts" And I attach the "t-shirts.jpg" image with "banner" type And I add it Then I should be notified that it has been successfully created @@ -24,6 +25,7 @@ Feature: Adding a new taxon with images When I want to create a new taxon And I specify its code as "t-shirts" And I name it "T-Shirts" in "English (United States)" + And I set its slug to "t-shirts" And I attach the "t-shirts.jpg" image with "banner" type And I attach the "t-shirts.jpg" image with "thumbnail" type And I add it diff --git a/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature b/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature index 6785abf8fc..e92aaecc91 100644 --- a/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature +++ b/features/admin/taxonomy/managing_taxons/adding_taxon_with_parent.feature @@ -9,7 +9,7 @@ Feature: Adding a new taxon with parent specified And the store has "Category" taxonomy And I am logged in as an administrator - @ui @javascript @api + @todo @ui @javascript @api Scenario: Adding a new taxon with parent When I want to create a new taxon And I set its parent taxon to "Category" diff --git a/features/admin/taxonomy/managing_taxons/browsing_taxon.feature b/features/admin/taxonomy/managing_taxons/browsing_taxon.feature index 203531ea23..ed00c83a69 100644 --- a/features/admin/taxonomy/managing_taxons/browsing_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/browsing_taxon.feature @@ -8,7 +8,7 @@ Feature: Browsing taxons Given the store classifies its products as "T-Shirts" and "Accessories" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing taxons in store When I want to see all taxons in store Then I should see 2 taxons on the list diff --git a/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature b/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature index 21820c9c3f..9c1ee01279 100644 --- a/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/changing_images_of_taxon.feature @@ -18,7 +18,7 @@ Feature: Changing images of an existing taxon Then I should be notified that it has been successfully edited And this taxon should have an image with "banner" type - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Changing the type of image of a taxon Given the "T-Shirts" taxon has an image "ford.jpg" with "thumbnail" type And the "T-Shirts" taxon also has an image "t-shirts.jpg" with "banner" type diff --git a/features/admin/taxonomy/managing_taxons/deleting_taxon.feature b/features/admin/taxonomy/managing_taxons/deleting_taxon.feature index 749b08ab21..34157dfcd7 100644 --- a/features/admin/taxonomy/managing_taxons/deleting_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/deleting_taxon.feature @@ -8,13 +8,13 @@ Feature: Deleting a taxon Given I am logged in as an administrator And the store operates on a channel named "Web Store" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Deleted taxon should disappear from the registry Given the store classifies its products as "T-Shirts" When I delete taxon named "T-Shirts" Then the taxon named "T-Shirts" should no longer exist in the registry - @ui @javascript @api + @todo @ui @javascript @api Scenario: Deleting a taxon with a child does not delete any other taxons Given the store classifies its products as "Main catalog" And the "Main catalog" taxon has children taxon "Shoes" and "Shovels" @@ -25,14 +25,14 @@ Feature: Deleting a taxon And the taxon named "Women" should no longer exist in the registry But the "Shovels" taxon should appear in the registry - @ui @javascript @api + @todo @ui @javascript @api Scenario: Being unable to delete a menu taxon of a channel Given the store classifies its products as "T-Shirts" and "Caps" And channel "Web Store" has menu taxon "Caps" When I try to delete taxon named "Caps" Then I should be notified that I cannot delete a menu taxon of any channel - @ui @javascript @api + @todo @ui @javascript @api Scenario: Deleting a taxon that is a main taxon of a product Given the store classifies its products as "T-Shirts" And the store has a product "T-Shirts PHP" @@ -41,7 +41,7 @@ Feature: Deleting a taxon Then the taxon named "T-Shirts" should no longer exist in the registry And the product "T-Shirts PHP" should no longer have a main taxon - @ui @javascript @api + @todo @ui @javascript @api Scenario: Deleting root taxon above menu taxon Given the store has "Main Category" taxonomy And the store has "Clothes Category" taxonomy diff --git a/features/admin/taxonomy/managing_taxons/editing_taxon.feature b/features/admin/taxonomy/managing_taxons/editing_taxon.feature index eeec5248a6..2c2f5395f6 100644 --- a/features/admin/taxonomy/managing_taxons/editing_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/editing_taxon.feature @@ -9,7 +9,7 @@ Feature: Editing a taxon And the store classifies its products as "T-Shirts" and "Accessories" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Renaming a taxon When I want to modify the "T-Shirts" taxon And I rename it to "Stickers" in "English (United States)" @@ -17,7 +17,7 @@ Feature: Editing a taxon Then I should be notified that it has been successfully edited And this taxon name should be "Stickers" - @ui @api + @todo @ui @api Scenario: Changing description When I want to modify the "T-Shirts" taxon And I change its description to "Main taxonomy for stickers" in "English (United States)" @@ -25,7 +25,7 @@ Feature: Editing a taxon Then I should be notified that it has been successfully edited And this taxon description should be "Main taxonomy for stickers" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Changing parent taxon When I want to modify the "T-Shirts" taxon And I change its parent taxon to "Accessories" @@ -33,7 +33,7 @@ Feature: Editing a taxon Then I should be notified that it has been successfully edited And this taxon should belongs to "Accessories" - @ui @api + @todo @ui @api Scenario: Being unable to change code of taxon When I want to modify the "T-Shirts" taxon Then I should not be able to edit its code diff --git a/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature b/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature index 950cb0789d..94c7cadc27 100644 --- a/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature +++ b/features/admin/taxonomy/managing_taxons/editing_taxon_slug.feature @@ -8,7 +8,7 @@ Feature: Editing taxon's slug Given the store is available in "English (United States)" And I am logged in as an administrator - @ui @javascript @api + @todo @ui @javascript @api Scenario: Creating a root taxon with an autogenerated slug When I want to create a new taxon And I specify its code as "MEDIEVAL_WEAPONS" @@ -16,7 +16,7 @@ Feature: Editing taxon's slug And I add it Then this taxon slug should be "medieval-weapons" - @ui @api + @todo @ui @api Scenario: Creating a root taxon with a custom slug When I want to create a new taxon And I specify its code as "MEDIEVAL_WEAPONS" @@ -25,7 +25,7 @@ Feature: Editing taxon's slug And I add it Then this taxon slug should be "mw" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Creating a child taxon with an autogenerated slug Given the store has "Medieval weapons" taxonomy When I want to create a new taxon for "Medieval weapons" @@ -34,7 +34,7 @@ Feature: Editing taxon's slug And I add it Then this taxon slug should be "medieval-weapons/siege-engines" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Creating a child taxon with autogenerated slug by setting the parent Given the store has "Medieval weapons" taxonomy When I want to create a new taxon @@ -44,7 +44,7 @@ Feature: Editing taxon's slug And I add it Then this taxon slug should be "medieval-weapons/pikes" - @ui @api + @todo @ui @api Scenario: Creating a child taxon with a custom slug Given the store has "Medieval weapons" taxonomy When I want to create a new taxon for "Medieval weapons" @@ -54,13 +54,13 @@ Feature: Editing taxon's slug And I add it Then this taxon slug should be "medieval-weapons/siege" - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled slug field when editing a taxon Given the store has "Medieval weapons" taxonomy When I want to modify the "Medieval weapons" taxon Then the slug field should not be editable - @ui @javascript @api + @todo @ui @javascript @api Scenario: Prevent from editing the slug while changing a taxon name Given the store has "Medieval weapons" taxonomy When I want to modify the "Medieval weapons" taxon @@ -68,7 +68,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Renaissance weapons" taxon should still be "medieval-weapons" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Prevent from editing the slug while setting the taxon's parent Given the store has "Medieval weapons" taxonomy And the store has "Pikes" taxonomy @@ -77,7 +77,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Pikes" taxon should still be "pikes" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Prevent from editing the slug while changing the taxon's parent Given the store has "Medieval weapons" taxonomy Given the store has "Renaissance weapons" taxonomy @@ -87,7 +87,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Pikes" taxon should still be "medieval-weapons/pikes" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Automatically changing a root taxon's slug while editing a taxon's name Given the store has "Medieval weapons" taxonomy When I want to modify the "Medieval weapons" taxon @@ -96,7 +96,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Renaissance weapons" taxon should be "renaissance-weapons" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Automatically changing a child taxon's slug while editing a taxon's name Given the store has "Medieval weapons" taxonomy And the "Medieval weapons" taxon has child taxon "Pikes" @@ -106,7 +106,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Javelins" taxon should be "medieval-weapons/javelins" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Manually changing a root taxon's slug while editing a taxon's name Given the store has "Medieval weapons" taxonomy When I want to modify the "Medieval weapons" taxon @@ -116,7 +116,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Renaissance weapons" taxon should be "renaissance" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Automatically changing a child taxon's slug when changing the parent Given the store has "Renaissance weapons" taxonomy And the store has "Medieval weapons" taxonomy @@ -127,7 +127,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Pikes" taxon should be "renaissance-weapons/pikes" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Manually changing a child taxon's slug when changing the parent Given the store has "Renaissance weapons" taxonomy And the store has "Medieval weapons" taxonomy @@ -139,7 +139,7 @@ Feature: Editing taxon's slug And I save my changes Then the slug of the "Pikes" taxon should be "pikes" - @ui @javascript @api + @todo @ui @javascript @api Scenario: Manually changing a child taxon's slug while editing a taxon's name Given the store has "Medieval weapons" taxonomy And the "Medieval weapons" taxon has child taxon "Pikes" diff --git a/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature b/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature index f65880cd0f..22a9cd8aba 100644 --- a/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature +++ b/features/admin/taxonomy/managing_taxons/editing_taxon_slug_in_multiple_locales.feature @@ -9,7 +9,7 @@ Feature: Editing taxon's slug in multiple locales And the store is also available in "Polish (Poland)" And I am logged in as an administrator - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Creating a root taxon with an autogenerated slug When I want to create a new taxon And I specify its code as "MEDIEVAL_WEAPONS" @@ -19,7 +19,7 @@ Feature: Editing taxon's slug in multiple locales Then this taxon should have slug "medieval-weapons" in "English (United States)" And this taxon should have slug "bronie-sredniowieczne" in "Polish (Poland)" - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Creating a child taxon with an autogenerated slug Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale When I want to create a new taxon for "Medieval weapons" @@ -30,7 +30,7 @@ Feature: Editing taxon's slug in multiple locales Then this taxon should have slug "medieval-weapons/siege-engines" in "English (United States)" And this taxon should have slug "bronie-sredniowieczne/machiny-obleznicze" in "Polish (Poland)" - @ui @api + @todo @ui @api Scenario: Creating a root taxon with a custom slug When I want to create a new taxon And I specify its code as "MEDIEVAL_WEAPONS" @@ -42,14 +42,14 @@ Feature: Editing taxon's slug in multiple locales Then this taxon should have slug "mw" in "English (United States)" And this taxon should have slug "bs" in "Polish (Poland)" - @ui @no-api + @todo @ui @no-api Scenario: Seeing disabled slug field when editing a taxon Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale When I want to modify the "Medieval weapons" taxon Then the slug field should not be editable in "English (United States)" Then the slug field should also not be editable in "Polish (Poland)" - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Prevent from editing a slug while changing a taxon name Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale When I want to modify the "Medieval weapons" taxon @@ -59,7 +59,7 @@ Feature: Editing taxon's slug in multiple locales Then this taxon should have slug "medieval-weapons" in "English (United States)" Then this taxon should have slug "bronie-sredniowieczne" in "Polish (Poland)" - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Automatically changing a taxon's slug while editing a taxon's name Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale When I want to modify the "Medieval weapons" taxon @@ -71,7 +71,7 @@ Feature: Editing taxon's slug in multiple locales Then this taxon should have slug "renaissance-weapons" in "English (United States)" Then this taxon should have slug "bronie-renesansowe" in "Polish (Poland)" - @ui @mink:chromedriver @api + @todo @ui @mink:chromedriver @api Scenario: Manually changing a taxon's slug while editing a taxon's name Given the store has taxonomy named "Medieval weapons" in "English (United States)" locale and "Bronie średniowieczne" in "Polish (Poland)" locale When I want to modify the "Medieval weapons" taxon diff --git a/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature b/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature index 72f507aad8..71dc0bcb28 100644 --- a/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/preventing_xss_attack_while_adding_new_taxon.feature @@ -10,7 +10,7 @@ Feature: Preventing a potential XSS attack while adding a new taxon And the store has "" taxonomy And I am logged in as an administrator - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Preventing a potential XSS attack while adding new taxon When I want to create a new taxon Then I should be able to change its parent taxon to "Category" diff --git a/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature b/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature index d1c4a3f595..6f9ff24f66 100644 --- a/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/removing_images_of_taxon.feature @@ -9,7 +9,7 @@ Feature: Removing images of an existing taxon And the store classifies its products as "T-Shirts" And I am logged in as an administrator - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing a single image of a taxon Given the "T-Shirts" taxon has an image "t-shirts.jpg" with "banner" type When I want to modify the "T-Shirts" taxon @@ -18,7 +18,7 @@ Feature: Removing images of an existing taxon Then I should be notified that the changes have been successfully applied And this taxon should not have any images - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing all images of a taxon Given the "T-Shirts" taxon has an image "t-shirts.jpg" with "banner" type And the "T-Shirts" taxon also has an image "t-shirts.jpg" with "thumbnail" type @@ -40,7 +40,7 @@ Feature: Removing images of an existing taxon And this taxon should have an image with "thumbnail" type But this taxon should not have any images with "banner" type - @ui @javascript @api + @ui @mink:chromedriver @api Scenario: Removing only one image of a taxon when all images have same type Given the "T-Shirts" taxon has an image "t-shirts.jpg" with "banner" type And the "T-Shirts" taxon also has an image "mugs.jpg" with "banner" type diff --git a/features/admin/taxonomy/managing_taxons/reordering_taxon.feature b/features/admin/taxonomy/managing_taxons/reordering_taxon.feature index a41db069d3..327c6a85d5 100644 --- a/features/admin/taxonomy/managing_taxons/reordering_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/reordering_taxon.feature @@ -8,7 +8,7 @@ Feature: Reordering taxons Given the store classifies its products as "T-Shirts", "Watches", "Belts" and "Wallets" And I am logged in as an administrator - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Moving up the taxon on list When I want to see all taxons in store And I move up "Watches" taxon @@ -16,7 +16,7 @@ Feature: Reordering taxons And I should see the taxon named "T-Shirts" in the list But the first taxon on the list should be "Watches" - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Moving down the taxon on list When I want to see all taxons in store And I move down "T-Shirts" taxon @@ -24,21 +24,21 @@ Feature: Reordering taxons And I should see the taxon named "Watches" in the list But the first taxon on the list should be "Watches" - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Moving up the first taxon on list When I want to see all taxons in store And I move up "T-Shirts" taxon Then I should see 4 taxons on the list And the first taxon on the list should be "T-Shirts" - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Moving down the last taxon on list When I want to see all taxons in store And I move down "Wallets" taxon Then I should see 4 taxons on the list And the last taxon on the list should be "Wallets" - @ui @javascript @no-api @todo + @todo @ui @javascript @no-api @todo Scenario: Changing order of the taxon on list When I want to see all taxons in store And I move down "T-Shirts" taxon diff --git a/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature b/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature index fb71180ba9..92d665076b 100644 --- a/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature +++ b/features/admin/taxonomy/managing_taxons/taxon_unique_code_validation.feature @@ -9,7 +9,7 @@ Feature: Taxon unique code validation And the store classifies its products as "T-Shirts" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add taxon with taken code When I want to create a new taxon And I specify its code as "t_shirts" diff --git a/features/admin/taxonomy/managing_taxons/taxon_validation.feature b/features/admin/taxonomy/managing_taxons/taxon_validation.feature index 051a53bae0..4cc246d772 100644 --- a/features/admin/taxonomy/managing_taxons/taxon_validation.feature +++ b/features/admin/taxonomy/managing_taxons/taxon_validation.feature @@ -16,7 +16,7 @@ Feature: Taxon validation And I save my changes Then I should be notified that the locale is not available - @ui @api + @todo @ui @api Scenario: Trying to add a taxon without specifying its code When I want to create a new taxon And I do not specify its code @@ -25,7 +25,7 @@ Feature: Taxon validation Then I should be notified that code is required And taxon named "T-Shirts" should not be added - @ui @api + @todo @ui @api Scenario: Trying to add a taxon without specifying its name When I want to create a new taxon And I specify its code as "t-shirts" @@ -33,7 +33,7 @@ Feature: Taxon validation And I try to add it Then I should be notified that name is required - @ui @api + @todo @ui @api Scenario: Trying to add a taxon with a too long code When I want to create a new taxon And I name it "T-Shirts" in "English (United States)" @@ -41,7 +41,7 @@ Feature: Taxon validation And I try to add it Then I should be notified that code is too long - @ui @no-api + @todo @ui @no-api Scenario: Trying to add a taxon without specifying its slug When I want to create a new taxon And I specify its code as "t-shirts" @@ -50,7 +50,7 @@ Feature: Taxon validation And I try to add it Then I should be notified that slug is required - @ui @api + @todo @ui @api Scenario: Trying to add a taxon with non unique slug Given the store classifies its products as "T-Shirts" When I want to create a new taxon diff --git a/features/admin/taxonomy/managing_taxons/toggling_taxon.feature b/features/admin/taxonomy/managing_taxons/toggling_taxon.feature index 2bdfa780ce..0458018e27 100644 --- a/features/admin/taxonomy/managing_taxons/toggling_taxon.feature +++ b/features/admin/taxonomy/managing_taxons/toggling_taxon.feature @@ -9,7 +9,7 @@ Feature: Toggling the taxon And the store classifies its products as "T-Shirts" and "Accessories" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a disabled taxon When I want to create a new taxon And I specify its code as "jeans" @@ -21,7 +21,7 @@ Feature: Toggling the taxon And the "Jeans" taxon should appear in the registry And it should be disabled - @ui @api + @todo @ui @api Scenario: Enabling a Taxon Given the "T-Shirts" taxon is disabled When I want to modify the "T-Shirts" taxon @@ -30,7 +30,7 @@ Feature: Toggling the taxon Then I should be notified that it has been successfully edited And it should be enabled - @ui @api + @todo @ui @api Scenario: Disabling a Taxon Given the "T-Shirts" taxon is enabled When I want to modify the "T-Shirts" taxon diff --git a/features/admin/user/managing_administrators/administrator_unique_email_and_name_validation.feature b/features/admin/user/managing_administrators/administrator_unique_email_and_name_validation.feature deleted file mode 100644 index 977585b9ea..0000000000 --- a/features/admin/user/managing_administrators/administrator_unique_email_and_name_validation.feature +++ /dev/null @@ -1,26 +0,0 @@ -@managing_administrators -Feature: Administrator unique email and name validation - In order to uniquely identify administrators - As an Administrator - I want to be prevented from adding two administrators with the same email or name - - Background: - Given I am logged in as an administrator - - @ui @api - Scenario: Trying to add a new administrator with taken email - Given there is an administrator "ted@example.com" - When I want to create a new administrator - And I specify its email as "ted@example.com" - And I try to add it - Then I should be notified that email must be unique - And there should still be only one administrator with an email "ted@example.com" - - @ui @api - Scenario: Trying to add a new administrator with taken name - Given there is an administrator with name "Ted" - When I want to create a new administrator - And I specify its name as "Ted" - And I try to add it - Then I should be notified that name must be unique - And there should still be only one administrator with name "Ted" diff --git a/features/admin/user/managing_administrators/administrator_validation.feature b/features/admin/user/managing_administrators/administrator_validation.feature index fea2b51831..f524b7a6b8 100644 --- a/features/admin/user/managing_administrators/administrator_validation.feature +++ b/features/admin/user/managing_administrators/administrator_validation.feature @@ -30,6 +30,24 @@ Feature: Administrator validation And I try to add it Then I should be notified that this email is not valid + @ui @api + Scenario: Trying to add a new administrator with taken email + Given there is an administrator "ted@example.com" + When I want to create a new administrator + And I specify its email as "ted@example.com" + And I try to add it + Then I should be notified that email must be unique + And there should still be only one administrator with an email "ted@example.com" + + @ui @api + Scenario: Trying to add a new administrator with taken name + Given there is an administrator with name "Ted" + When I want to create a new administrator + And I specify its name as "Ted" + And I try to add it + Then I should be notified that name must be unique + And there should still be only one administrator with name "Ted" + @ui @api Scenario: Trying to add a new administrator with too long username specified When I want to create a new administrator diff --git a/features/admin/user/managing_administrators/deleting_multiple_administrators.feature b/features/admin/user/managing_administrators/deleting_multiple_administrators.feature index 16c2661b6f..a9f0feeb24 100644 --- a/features/admin/user/managing_administrators/deleting_multiple_administrators.feature +++ b/features/admin/user/managing_administrators/deleting_multiple_administrators.feature @@ -10,7 +10,7 @@ Feature: Deleting multiple administrators And there is also an administrator "watermelon@example.com" And I am logged in as "watermelon@example.com" administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple administrators at once Given I browse administrators And I check the "banana@example.com" administrator diff --git a/features/admin/user/managing_customer_groups/adding_customer_group.feature b/features/admin/user/managing_customer_groups/adding_customer_group.feature index db3b32bd85..b57e3e67a6 100644 --- a/features/admin/user/managing_customer_groups/adding_customer_group.feature +++ b/features/admin/user/managing_customer_groups/adding_customer_group.feature @@ -7,7 +7,7 @@ Feature: Adding a new customer group Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Adding a new customer group When I want to create a new customer group And I specify its code as "RETAIL" diff --git a/features/admin/user/managing_customer_groups/browsing_customer_groups.feature b/features/admin/user/managing_customer_groups/browsing_customer_groups.feature index 78d76a43be..0e03c1d14a 100644 --- a/features/admin/user/managing_customer_groups/browsing_customer_groups.feature +++ b/features/admin/user/managing_customer_groups/browsing_customer_groups.feature @@ -9,7 +9,7 @@ Feature: Browsing customer groups And the store has a customer group "Wholesale" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Browsing customer groups in the store When I want to browse customer groups Then I should see 2 customer groups in the list diff --git a/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature b/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature index d3708fc73d..ef88457d4a 100644 --- a/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature +++ b/features/admin/user/managing_customer_groups/customer_group_unique_code_validation.feature @@ -8,7 +8,7 @@ Feature: Customer group unique code validation Given the store has a customer group "Retail" with "RETAIL" code And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new customer group with used code When I want to create a new customer group And I specify its code as "RETAIL" diff --git a/features/admin/user/managing_customer_groups/customer_group_validation.feature b/features/admin/user/managing_customer_groups/customer_group_validation.feature index 6e4a460cad..b3d6ca4b6e 100644 --- a/features/admin/user/managing_customer_groups/customer_group_validation.feature +++ b/features/admin/user/managing_customer_groups/customer_group_validation.feature @@ -7,14 +7,14 @@ Feature: Customer group validation Background: Given I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Trying to add a new customer group without a name 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 - @ui @api + @todo @ui @api Scenario: Trying to remove name from an existing customer group Given the store has a customer group "Retail" When I want to edit this customer group diff --git a/features/admin/user/managing_customer_groups/deleting_customer_group.feature b/features/admin/user/managing_customer_groups/deleting_customer_group.feature index 5e7e60bbce..3a3f81e503 100644 --- a/features/admin/user/managing_customer_groups/deleting_customer_group.feature +++ b/features/admin/user/managing_customer_groups/deleting_customer_group.feature @@ -8,7 +8,7 @@ Feature: Deleting customer groups Given the store has a customer group "Retail" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Deleting a customer group When I delete the "Retail" customer group Then I should be notified that it has been successfully deleted diff --git a/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature b/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature index c4b23d1a1d..b71a44cd79 100644 --- a/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature +++ b/features/admin/user/managing_customer_groups/deleting_multiple_customer_groups.feature @@ -8,7 +8,7 @@ Feature: Deleting multiple customer groups Given the store has customer groups "Retail", "Wholesale" and "General" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Deleting multiple customer groups at once When I browse customer groups And I check the "Retail" customer group diff --git a/features/admin/user/managing_customer_groups/editing_customer_group.feature b/features/admin/user/managing_customer_groups/editing_customer_group.feature index 2889afd97c..5c28d88a5a 100644 --- a/features/admin/user/managing_customer_groups/editing_customer_group.feature +++ b/features/admin/user/managing_customer_groups/editing_customer_group.feature @@ -8,7 +8,7 @@ Feature: Editing a customer group Given the store has a customer group "Retail" And I am logged in as an administrator - @ui @api + @todo @ui @api Scenario: Changing name of an existing customer group When I want to edit this customer group And I specify its name as "Wholesale" @@ -16,7 +16,7 @@ Feature: Editing a customer group Then I should be notified that it has been successfully edited And this customer group with name "Wholesale" should appear in the store - @ui @api + @todo @ui @api Scenario: Seeing disabled code field while editing customer group When I want to edit this customer group Then I should not be able to edit its code diff --git a/features/admin/user/managing_customers/adding_customer.feature b/features/admin/user/managing_customers/adding_customer.feature index 0029390f2b..62906b7ab8 100644 --- a/features/admin/user/managing_customers/adding_customer.feature +++ b/features/admin/user/managing_customers/adding_customer.feature @@ -8,7 +8,7 @@ Feature: Adding a new customer Given the store has a customer group "Retail" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Adding a new customer When I want to create a new customer And I specify their email as "l.skywalker@gmail.com" @@ -16,7 +16,7 @@ Feature: Adding a new customer Then I should be notified that it has been successfully created And the customer "l.skywalker@gmail.com" should appear in the store - @api @ui + @api @todo @ui Scenario: Adding a new customer with full details When I want to create a new customer And I specify their first name as "Luke" diff --git a/features/admin/user/managing_customers/adding_customer_account.feature b/features/admin/user/managing_customers/adding_customer_account.feature index cab1ba145b..38d1e1f5e9 100644 --- a/features/admin/user/managing_customers/adding_customer_account.feature +++ b/features/admin/user/managing_customers/adding_customer_account.feature @@ -7,7 +7,7 @@ Feature: Adding a new customer account Background: Given I am logged in as an administrator - @api @ui @javascript + @api @todo @ui @javascript Scenario: Adding a new customer with an account When I want to create a new customer account And I specify their email as "l.skywalker@gmail.com" @@ -18,7 +18,7 @@ Feature: Adding a new customer account And the customer "l.skywalker@gmail.com" should appear in the store And the customer "l.skywalker@gmail.com" should have an account created - @api @ui @javascript + @api @todo @ui @javascript Scenario: Creating an account for existing customer Given the store has customer "Frodo Baggins" with email "f.baggins@example.com" When I want to edit this customer diff --git a/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature b/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature index 2aea8c7994..f0a35533a8 100644 --- a/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature +++ b/features/admin/user/managing_customers/adding_customer_account_after_failed_creation_action.feature @@ -7,7 +7,7 @@ Feature: Adding a new customer account after failed creation action Background: Given I am logged in as an administrator - @api @ui @javascript + @api @todo @ui @javascript Scenario: Trying to add new customer with an account without required information When I want to create a new customer account And I choose create account option @@ -19,7 +19,7 @@ Feature: Adding a new customer account after failed creation action And I should be notified that email is required And I should be notified that password is required - @api @ui @javascript + @api @todo @ui @javascript Scenario: Trying to add new customer with an account without email When I want to create a new customer account And I choose create account option @@ -31,7 +31,7 @@ Feature: Adding a new customer account after failed creation action And I should not be able to select create account option And I should be notified that email is required - @api @ui @javascript + @api @todo @ui @javascript Scenario: Trying to add new customer without an account without email When I want to create a new customer account And I do not choose create account option @@ -42,7 +42,7 @@ Feature: Adding a new customer account after failed creation action And I should be able to select create account option And I should be notified that email is required - @api @ui @javascript + @api @todo @ui @javascript Scenario: Trying to add new customer with an account without required information When I want to create a new customer account And I choose create account option diff --git a/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature b/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature index 5897ab42d0..730d14acfc 100644 --- a/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature +++ b/features/admin/user/managing_customers/being_able_to_create_account_for_existing_customer.feature @@ -7,7 +7,7 @@ Feature: Create account option availability Background: And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Being able to create an account for created customer When I want to create a new customer And I do not choose create account option @@ -17,7 +17,7 @@ Feature: Create account option availability And I should not be able to specify their password And I should be able to select create account option - @ui @javascript @no-api + @todo @ui @javascript @no-api Scenario: Not seeing create account option after adding customer with account When I want to create a new customer account And I choose create account option diff --git a/features/admin/user/managing_customers/changing_customer_email.feature b/features/admin/user/managing_customers/changing_customer_email.feature index 02317b7674..fda68e56d1 100644 --- a/features/admin/user/managing_customers/changing_customer_email.feature +++ b/features/admin/user/managing_customers/changing_customer_email.feature @@ -9,7 +9,7 @@ Feature: Changing an email of an existing customer And there is a customer "Frodo Baggins" with an email "f.baggins@example.com" and a password "ring" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Changing an email of an existing customer When I want to edit this customer And I change their email to "strawberry@example.com" diff --git a/features/admin/user/managing_customers/customer_unique_email_validation.feature b/features/admin/user/managing_customers/customer_unique_email_validation.feature index 582e06294b..542415d51a 100644 --- a/features/admin/user/managing_customers/customer_unique_email_validation.feature +++ b/features/admin/user/managing_customers/customer_unique_email_validation.feature @@ -7,7 +7,7 @@ Feature: Customer uniqueness of email validation Background: Given I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Trying to add a new customer with taken email Given the store has customer "f.baggins@example.com" When I want to create a new customer diff --git a/features/admin/user/managing_customers/customer_validation.feature b/features/admin/user/managing_customers/customer_validation.feature index f9ff6b850a..42896b019b 100644 --- a/features/admin/user/managing_customers/customer_validation.feature +++ b/features/admin/user/managing_customers/customer_validation.feature @@ -7,7 +7,7 @@ Feature: Customer validation Background: Given I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Trying to add a new customer without an email When I want to create a new customer And I specify their first name as "Luke" @@ -15,7 +15,7 @@ Feature: Customer validation And I try to add them Then I should be notified that email is required - @api @ui + @api @todo @ui Scenario: Trying to specify too short first name for an existing customer Given the store has customer "l.skywalker@gmail.com" When I want to edit this customer @@ -24,7 +24,7 @@ Feature: Customer validation Then I should be notified that first name should be at least 2 characters long And the customer "l.skywalker@gmail.com" should still have an empty first name - @api @ui + @api @todo @ui Scenario: Trying to specify too short last name for an existing customer Given the store has customer "l.skywalker@gmail.com" with first name "Luke" When I want to edit this customer @@ -33,7 +33,7 @@ Feature: Customer validation Then I should be notified that last name should be at least 2 characters long And the customer "l.skywalker@gmail.com" should still have an empty last name - @api @ui + @api @todo @ui Scenario: Trying to remove email from an existing customer Given the store has customer "l.skywalker@gmail.com" When I want to edit this customer @@ -42,7 +42,7 @@ Feature: Customer validation Then I should be notified that email is required And the customer "l.skywalker@gmail.com" should still have this email - @api @ui + @api @todo @ui Scenario: Trying to create customer with wrong email format When I want to create a new customer And I specify their email as "wrongemail" @@ -50,7 +50,7 @@ Feature: Customer validation Then I should be notified that email is not valid And the customer with email "wrongemail" should not appear in the store - @api @ui + @api @todo @ui Scenario: Trying to create customer with wrong email format in strict mode When I want to create a new customer And I specify their email as "wrongemail@example..com" diff --git a/features/admin/user/managing_customers/editing_customer.feature b/features/admin/user/managing_customers/editing_customer.feature index 1fe8b28fc2..57638adbaf 100644 --- a/features/admin/user/managing_customers/editing_customer.feature +++ b/features/admin/user/managing_customers/editing_customer.feature @@ -7,7 +7,7 @@ Feature: Editing a customer Background: Given I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Changing first and last name of an existing customer Given the store has customer "Frodo Baggins" with email "f.baggins@example.com" When I want to edit this customer @@ -17,7 +17,7 @@ Feature: Editing a customer Then I should be notified that it has been successfully edited And this customer with name "Jon Snow" should appear in the store - @api @ui + @api @todo @ui Scenario: Removing first and last name from an existing customer Given the store has customer "Luke Skywalker" with email "l.skywalker@gmail.com" When I want to edit this customer @@ -28,7 +28,7 @@ Feature: Editing a customer And this customer should have an empty first name And this customer should have an empty last name - @api @ui + @api @todo @ui Scenario: Making an existing customer subscribed to the newsletter Given the store has customer "Mike Ross" with email "ross@teammike.com" When I want to edit this customer @@ -37,7 +37,7 @@ Feature: Editing a customer Then I should be notified that it has been successfully edited And this customer should be subscribed to the newsletter - @api @ui + @api @todo @ui Scenario: Selecting a group for an existing customer Given the store has a customer group "Retail" And the store has customer "Mike Ross" with email "ross@teammike.com" diff --git a/features/admin/user/managing_customers/customer_filtration/filtering_customers_by_groups.feature b/features/admin/user/managing_customers/filtering_customers_by_groups.feature similarity index 97% rename from features/admin/user/managing_customers/customer_filtration/filtering_customers_by_groups.feature rename to features/admin/user/managing_customers/filtering_customers_by_groups.feature index e94cd200fe..a29d643664 100644 --- a/features/admin/user/managing_customers/customer_filtration/filtering_customers_by_groups.feature +++ b/features/admin/user/managing_customers/filtering_customers_by_groups.feature @@ -14,7 +14,7 @@ Feature: Filtering customers by groups And this customer belongs to group "Wholesale" And I am logged in as an administrator - @api @ui @javascript + @api @ui @mink:chromedriver Scenario: Filtering customers by a group When I want to see all customers in store And I filter by group "Retail" diff --git a/features/admin/user/managing_customers/filtering_customers_by_search.feature b/features/admin/user/managing_customers/filtering_customers_by_search.feature new file mode 100644 index 0000000000..c976471a9e --- /dev/null +++ b/features/admin/user/managing_customers/filtering_customers_by_search.feature @@ -0,0 +1,33 @@ +@managing_customers +Feature: Filtering customers by firstname, lastname and email + In order to quickly find customers + As an Administrator + I want to search for a specific customer + + Background: + Given there is a customer "Frodo Baggins" with an email "f.baggins@shire.me" + And there is a customer "Ghastly Bespoke" with an email "g.bespoke@example.com" + And there is a customer "Lirael Abhorsen" with an email "l.abhorsen@example.me" + And I am logged in as an administrator + + @ui @api-todo + Scenario: Searching customers by email + When I want to see all customers in store + And I search for customer by "e.me" + Then I should see 2 customers on the list + And I should see the customer "f.baggins@shire.me" on the list + And I should see the customer "l.abhorsen@example.me" on the list + + @ui @api-todo + Scenario: Filtering customers by firstname + When I want to see all customers in store + And I search for customer by "Lirael" + Then I should see a single customer on the list + And I should see the customer "l.abhorsen@example.me" on the list + + @ui @api-todo + Scenario: Filtering customers by lastname + When I want to see all customers in store + And I search for customer by "Bespoke" + Then I should see a single customer on the list + And I should see the customer "g.bespoke@example.com" on the list diff --git a/features/admin/user/managing_customers/resetting_customer_password.feature b/features/admin/user/managing_customers/resetting_customer_password.feature index 3e06cb2034..8cbf9e6cc9 100644 --- a/features/admin/user/managing_customers/resetting_customer_password.feature +++ b/features/admin/user/managing_customers/resetting_customer_password.feature @@ -8,7 +8,7 @@ Feature: Resetting a customer's password Given there is a user "goodman@example.com" identified by "heisenberg" And I am logged in as an administrator - @ui @todo + @todo @ui @todo Scenario: Sending reset password email to a customer When I view details of the customer "goodman@example.com" And I reset their password diff --git a/features/admin/user/managing_customers/seeing_customer_details.feature b/features/admin/user/managing_customers/seeing_customer_details.feature index e2919aebfd..f22a15c941 100644 --- a/features/admin/user/managing_customers/seeing_customer_details.feature +++ b/features/admin/user/managing_customers/seeing_customer_details.feature @@ -6,7 +6,6 @@ Feature: Seeing customer's details Background: Given I am logged in as an administrator - And the store has a customer group Retail And the store has customer "f.baggins@shire.me" with name "Frodo Baggins" and phone number "666777888" since "2011-01-10 21:00" @api @ui @@ -37,7 +36,8 @@ Feature: Seeing customer's details @api @ui Scenario: Seeing information about customer groups - Given the customer belongs to group "Retail" + Given the store has a customer group Retail + And the customer belongs to group "Retail" When I view details of the customer "f.baggins@shire.me" Then this customer should have "Retail" as their group diff --git a/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature b/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature index e7d327024a..b0b4f7ed82 100644 --- a/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature +++ b/features/admin/user/managing_customers/seeing_orders_statistics_on_customer_details_page.feature @@ -36,4 +36,4 @@ Feature: Seeing customer's orders' statistics Given customer "lirael.clayr@abhorsen.ok" has fulfilled 12 orders placed on the "Web-UK" channel in each buying 2 "Onion" products And customer "lirael.clayr@abhorsen.ok" has placed 2 orders on the "Web-UK" channel in each buying 2 "Onion" products When I view their details - Then I should see that the average total value of their order in the "Web-UK" channel is "£2,400.00" + Then I should see that the average total value of their order in the "Web-UK" channel is "£200.00" diff --git a/features/admin/user/managing_customers/sorting_customers.feature b/features/admin/user/managing_customers/sorting_customers.feature new file mode 100644 index 0000000000..8c6d893182 --- /dev/null +++ b/features/admin/user/managing_customers/sorting_customers.feature @@ -0,0 +1,74 @@ +@managing_customers +Feature: Filtering customers by firstname, lastname and email + In order to quickly find customers + As an Administrator + I want to search for a specific customer + + Background: + Given the store has customer "f.baggins@shire.me" with name "Frodo Baggins" since "2011-01-10 21:00" + And the store has customer "l.abhorsen@example.com" with name "Lirael Abhorsen" since "2020-01-01 10:00" + And the store has customer "g.bespoke@example.com" with name "Ghastly Bespoke" since "2000-10-11 15:00" + And I am logged in as an administrator + + @ui @api-todo + Scenario: Customers are sorted by descending registration date + When I want to see all customers in store + Then I should see 3 customers on the list + And the first customer should be "l.abhorsen@example.com" + And the last customer should be "g.bespoke@example.com" + + @ui @api-todo + Scenario: Sorting customers by ascending registration date + When I want to see all customers in store + And I sort customers by ascending registration date + Then I should see 3 customers on the list + And the first customer should be "g.bespoke@example.com" + And the last customer should be "l.abhorsen@example.com" + + @ui @api-todo + Scenario: Sorting customers by descending email + When I want to see all customers in store + And I sort customers by descending email + Then I should see 3 customers on the list + And the first customer should be "l.abhorsen@example.com" + And the last customer should be "f.baggins@shire.me" + + @ui @api-todo + Scenario: Sorting customers by ascending email + When I want to see all customers in store + And I sort customers by ascending email + Then I should see 3 customers on the list + And the first customer should be "f.baggins@shire.me" + And the last customer should be "l.abhorsen@example.com" + + @ui @api-todo + Scenario: Sorting customers by descending first name + When I want to see all customers in store + And I sort customers by descending first name + Then I should see 3 customers on the list + And the first customer should be "l.abhorsen@example.com" + And the last customer should be "f.baggins@shire.me" + + @ui @api-todo + Scenario: Sorting customers by ascending first name + When I want to see all customers in store + And I sort customers by ascending first name + Then I should see 3 customers on the list + And the first customer should be "f.baggins@shire.me" + And the last customer should be "l.abhorsen@example.com" + + @ui @api-todo + Scenario: Sorting customers by descending last name + When I want to see all customers in store + And I sort customers by descending last name + Then I should see 3 customers on the list + And the first customer should be "g.bespoke@example.com" + And the last customer should be "l.abhorsen@example.com" + + @ui @api-todo + Scenario: Sorting customers by ascending last name + When I want to see all customers in store + And I sort customers by ascending last name + Then I should see 3 customers on the list + And the first customer should be "l.abhorsen@example.com" + And the last customer should be "g.bespoke@example.com" diff --git a/features/admin/user/managing_customers/toggling_customer_account.feature b/features/admin/user/managing_customers/toggling_customer_account.feature index d2844b4e54..75c25fa678 100644 --- a/features/admin/user/managing_customers/toggling_customer_account.feature +++ b/features/admin/user/managing_customers/toggling_customer_account.feature @@ -7,7 +7,7 @@ Feature: Toggling a customer account Background: Given I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Enabling a customer account Given there is disabled customer account "f.baggins@example.com" with password "psw" When I want to enable "f.baggins@example.com" @@ -16,7 +16,7 @@ Feature: Toggling a customer account Then I should be notified that it has been successfully edited And this customer should be enabled - @api @ui + @api @todo @ui Scenario: Disabling a customer account Given there is enabled customer account "f.baggins@example.com" with password "psw" When I want to disable "f.baggins@example.com" diff --git a/features/admin/user/managing_customers/verifying_customer_account.feature b/features/admin/user/managing_customers/verifying_customer_account.feature index 3060e99fb7..0c4696910c 100644 --- a/features/admin/user/managing_customers/verifying_customer_account.feature +++ b/features/admin/user/managing_customers/verifying_customer_account.feature @@ -7,7 +7,7 @@ Feature: Toggling a customer account Background: Given I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Verifying customer account Given there is enabled customer account "f.baggins@example.com" with password "psw" When I want to verify "f.baggins@example.com" diff --git a/features/admin/user/managing_users/changing_shop_user_password.feature b/features/admin/user/managing_users/changing_shop_user_password.feature index b05422d149..b4241d5b08 100644 --- a/features/admin/user/managing_users/changing_shop_user_password.feature +++ b/features/admin/user/managing_users/changing_shop_user_password.feature @@ -9,7 +9,7 @@ Feature: Changing shop user's password And there is a user "kibsoon@example.com" identified by "goodGuy" And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Changing a password of a shop user When I change the password of user "kibsoon@example.com" to "veryGoodGuy" Then I should be notified that it has been successfully edited diff --git a/features/domain/cart/deleting_expired_carts_automatically.feature b/features/domain/cart/deleting_expired_carts_automatically.feature deleted file mode 100644 index 3e4c453d2c..0000000000 --- a/features/domain/cart/deleting_expired_carts_automatically.feature +++ /dev/null @@ -1,20 +0,0 @@ -@shopping_cart -Feature: Deleting expired carts automatically - In order to remove started but not finished orders after 2 days of idleness - As an Administrator - I want to have expired carts automatically deleted - - Background: - Given the store operates on a single channel in "United States" - - @domain - Scenario: Having cart deleted after 4 days of idleness - Given a customer "john.doe@gmail.com" added something to cart - And he abandoned the cart 4 days ago - Then this cart should be automatically deleted - - @domain - Scenario: Having idle cart in registry if expiration time has not been reached - Given a customer "john.doe@gmail.com" added something to cart - And he abandoned the cart 1 day ago - Then this cart should not be deleted diff --git a/features/domain/order/cancelling_unpaid_orders_automatically.feature b/features/domain/order/cancelling_unpaid_orders_automatically.feature deleted file mode 100644 index bcf3aa78e1..0000000000 --- a/features/domain/order/cancelling_unpaid_orders_automatically.feature +++ /dev/null @@ -1,27 +0,0 @@ -@managing_orders -Feature: Cancelling unpaid orders automatically - In order to get rid of completed orders after 5 days of being unpaid - As an Administrator - I want to have unpaid orders automatically cancelled - - Background: - Given the store operates on a single channel in "United States" - And the store has a product "PHP T-Shirt" priced at "$10.00" in "United States" channel - And the store ships everywhere for Free - And the store allows paying with "Paypal Express Checkout" - - @domain - Scenario: Having order cancelled after 10 days of being unpaid - Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" - And the customer bought a single "PHP T-Shirt" - And the customer chose "Free" shipping method to "United States" with "Paypal Express Checkout" payment - When this order has not been paid for 10 days - Then this order should be automatically cancelled - - @domain - Scenario: Having unpaid order not cancelled if expiration time has not been reached - Given there is a customer "john.doe@gmail.com" that placed an order "#00000022" - And the customer bought a single "PHP T-Shirt" - And the customer chose "Free" shipping method to "United States" with "Paypal Express Checkout" payment - When this order has not been paid for 2 days - Then this order should not be cancelled diff --git a/features/domain/order/deleting_order.feature b/features/domain/order/deleting_order.feature deleted file mode 100644 index 19e260a763..0000000000 --- a/features/domain/order/deleting_order.feature +++ /dev/null @@ -1,45 +0,0 @@ -@managing_orders -Feature: Deleting an order - In order to to remove test, obsolete or incorrect orders - As an Administrator - I want to be able to delete an order with all it's details from the registry - - Background: - Given the store operates on a single channel in "United States" - And the store has a product "PHP T-Shirt" - And the store ships everywhere for Free - And the store allows paying with "Cash on Delivery" - And there is a customer "john.doe@gmail.com" that placed an order "#00000022" - And the customer bought a single "PHP T-Shirt" - And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment - And I am logged in as an administrator - - @domain - Scenario: Deleted order should disappear from the registry - When I delete the order "#00000022" - Then this order should not exist in the registry - - @domain - Scenario: Payments of a deleted order should disappear from the registry - When I delete the order "#00000022" - Then there should be no "Cash on Delivery" payments in the registry - - @domain - Scenario: Shipments of a deleted order should disappear from the registry - When I delete the order "#00000022" - Then there should be no shipments with "Free" shipping method in the registry - - @domain - Scenario: Order items are deleted together with an order - When I delete the order "#00000022" - Then the order item with product "PHP T-Shirt" should not exist - - @domain - Scenario: Order adjustments are deleted together with an order - When I delete the order "#00000022" - Then adjustments of this order should not exist - - @domain - Scenario: Billing and shipping addresses are deleted with an order - When I delete the order "#00000022" - Then billing and shipping addresses of this order should not exist diff --git a/features/domain/product/deleting_old_channel_pricing_entry_logs.feature b/features/domain/product/deleting_old_channel_pricing_entry_logs.feature deleted file mode 100644 index ad40222dd7..0000000000 --- a/features/domain/product/deleting_old_channel_pricing_entry_logs.feature +++ /dev/null @@ -1,31 +0,0 @@ -@managing_price_history -Feature: Deleting old channel pricing entry logs - In order to keep the price history slim - As an Administrator - I want to delete old channel pricing entry logs - - Background: - Given the store operates on a single channel in "United States" - And it is "2022-03-14" now - And the store has a product "PHP T-Shirt" priced at "$10.00" - And on "2022-03-20" its price changed to "$20.00" - And on "2022-03-29" its original price changed to "$25.00" - And on "2022-04-14" its price changed to "$15.00" and original price to "$30.00" - And on "2022-04-20" its original price has been removed - And it is "2022-04-29" now - - @domain - Scenario: Deleting price history older than 90 days - When I delete price history older than 90 days - Then there should be 5 price history entries for this product - - @domain - Scenario: Deleting price history older than 30 days - When I delete price history older than 30 days - Then there should be 2 price history entries for this product - And this product should have no entry with original price changed to "$25.00" - - @domain - Scenario: Deleting price history older than 1 day - When I delete price history older than 1 day - Then this product's price history should be empty diff --git a/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature b/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature index 7fa12158a4..0387928dd8 100644 --- a/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature +++ b/features/hybrid/checkout/assigning_customer_ip_address_to_placed_order.feature @@ -13,7 +13,7 @@ Feature: Assigning customer's IP address to a placed order And there is a customer account "customer@example.com" identified by "sylius" And I am logged in as "customer@example.com" - @ui + @todo @ui Scenario: Assigning customer's IP address to a newly placed order Given I have product "PHP T-Shirt" in the cart And I specified the billing address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow" diff --git a/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature b/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature index 7361172e46..6be63148ba 100644 --- a/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature +++ b/features/hybrid/checkout/leaving_notes_on_order_during_checkout.feature @@ -13,7 +13,7 @@ Feature: Leaving additional request notes on my order during checkout And there is a customer account "customer@example.com" identified by "sylius" And I am logged in as "customer@example.com" - @ui @api + @todo @ui @api Scenario: Adding note on the checkout summary step Given I have product "PHP T-Shirt" in the cart And I specified the billing address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow" diff --git a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature index 08890889f4..ac71f2e99f 100644 --- a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature +++ b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_a_single_channel_store.feature @@ -16,7 +16,7 @@ Feature: Placing an order on a single channel store And there is a customer account "customer@example.com" identified by "sylius" And I am logged in as "customer@example.com" - @ui + @todo @ui Scenario: Placing an order in a channels base currency Given I have product "PHP T-Shirt" in the cart And I specified the billing address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow" @@ -24,7 +24,7 @@ Feature: Placing an order on a single channel store And I confirm my order Then the administrator should see that order placed by "customer@example.com" has "USD" currency - @ui @no-api + @todo @ui @no-api Scenario: Placing an order in a channels base currency displaying prices in other currency Given that channel also allows to shop using the "CAD" currency And I had product "PHP T-Shirt" in the cart diff --git a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature index 3a42742c0e..4ff38f03b2 100644 --- a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature +++ b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_different_currency.feature @@ -17,7 +17,7 @@ Feature: Placing an order on multiple channels with different currency And there is a customer account "customer@example.com" identified by "sylius" And I am logged in as "customer@example.com" - @ui @api + @todo @ui @api Scenario: Placing an order in a channels base currency Given I changed my current channel to "United States" And I have product "PHP T-Shirt" in the cart @@ -26,7 +26,7 @@ Feature: Placing an order on multiple channels with different currency And I confirm my order Then the administrator should see that order placed by "customer@example.com" has "USD" currency - @ui @api + @todo @ui @api Scenario: Placing an order on a different channel with same currency Given I changed my current channel to "Colombia" And I had product "PHP T-Shirt" in the cart diff --git a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature index 24ebe67960..91dc157d0a 100644 --- a/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature +++ b/features/hybrid/checkout/placing_order_on_multi_channel/placing_an_order_on_multiple_channels_with_same_currency.feature @@ -17,7 +17,7 @@ Feature: Placing an order on multiple channels with same currency And there is a customer account "customer@example.com" identified by "sylius" And I am logged in as "customer@example.com" - @ui + @todo @ui Scenario: Placing an order in a channels base currency Given I changed my current channel to "Web" And I have product "PHP T-Shirt" in the cart @@ -26,7 +26,7 @@ Feature: Placing an order on multiple channels with same currency And I confirm my order Then the administrator should see that order placed by "customer@example.com" has "USD" currency - @ui + @todo @ui Scenario: Placing an order on a different channel with same currency Given I changed my current channel to "Mobile" And I had product "PHP T-Shirt" in the cart diff --git a/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature b/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature index 02be72c5d7..35653155d9 100644 --- a/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature +++ b/features/hybrid/promotion/applying_catalog_promotions/applying_catalog_promotions_for_product_created_in_catalog_promotions_scope.feature @@ -9,13 +9,13 @@ Feature: Applying catalog promotions for product created in catalog promotions s And the store classifies its products as "Clothes" and "Dishes" And I am logged in as an administrator - @ui @mink:chromedriver @no-api + @todo @ui @mink:chromedriver @no-api Scenario: Applying catalog promotion on newly created simple product Given there is a catalog promotion "Clothes sale" that reduces price by "30%" and applies on "Clothes" taxon When I create a new simple product "T-Shirt" priced at "$20.00" with "Clothes" taxon in the "United States" channel Then the visitor should see "$14.00" as the price of the "T-Shirt" product in the "United States" channel - @api @ui + @api @todo @ui Scenario: Applying catalog promotion on newly created product variant Given there is a catalog promotion "Clothes sale" that reduces price by "30%" and applies on "Clothes" taxon And the store has a "T-Shirt" configurable product @@ -23,7 +23,7 @@ Feature: Applying catalog promotions for product created in catalog promotions s When I create a new "PHP T-Shirt" variant priced at "$20.00" for "T-Shirt" product in the "United States" channel Then the visitor should see "$14.00" as the price of the "T-Shirt" product in the "United States" channel - @api @ui + @api @todo @ui Scenario: Not applying catalog promotion on newly created product variant if it's not eligible Given there is a catalog promotion "Clothes sale" that reduces price by "30%" and applies on "Clothes" taxon And the store has a "Plate" configurable product diff --git a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature index b7dd344f27..1cf3d378fc 100644 --- a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature +++ b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature @@ -14,12 +14,12 @@ Feature: Not reapplying catalog promotions on variant once its prices changes And there is disabled catalog promotion "Surprise sale" between "2021-07-01" and "2022-05-04" available in "Web-US" channel that reduces price by "90%" and applies on "PHP T-Shirt" variant And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Changing the price of the variant When I change the price of the "PHP T-Shirt" product variant to "$50.00" in "Web-US" channel Then the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-US" channel - @api @ui + @api @todo @ui Scenario: Changing the original price of the variant When I change the original price of the "PHP T-Shirt" product variant to "$105.00" in "Web-US" channel Then the visitor should see "$100.00" as the price of the "T-Shirt" product in the "Web-US" channel diff --git a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature index c9cd8bf966..556782973c 100644 --- a/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature +++ b/features/hybrid/promotion/applying_catalog_promotions/not_reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature @@ -16,14 +16,14 @@ Feature: Not reapplying catalog promotions on variants once the product’s taxo And there is disabled catalog promotion "Surprise sale" between "2021-07-01" and "2022-05-04" available in "Web-US" channel that reduces price by "90%" and applies on "Dishes" taxon And I am logged in as an administrator - @api @ui + @api @todo @ui Scenario: Changing products taxon to taxon with scheduled catalog promotion When I change that the "T-Shirt" product does not belong to the "Clothes" taxon And I add "Shirts" taxon to the "T-Shirt" product Then the visitor should see that the "PHP T-Shirt" variant is not discounted And the visitor should still see "$100.00" as the price of the "T-Shirt" product in the "Web-US" channel - @api @ui + @api @todo @ui Scenario: Changing products taxon to taxon with disabled catalog promotion When I change that the "T-Shirt" product does not belong to the "Clothes" taxon And I add "Dishes" taxon to the "T-Shirt" product diff --git a/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature b/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature index a0bdae1487..5f6d8c2d39 100644 --- a/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature +++ b/features/shop/checkout/paying_for_order/paying_with_paypal_during_checkout.feature @@ -7,7 +7,7 @@ Feature: Paying with paypal during checkout Background: Given the store operates on a single channel in "United States" And there is a user "john@example.com" identified by "password123" - And the store has a payment method "PayPal" with a code "PAYPAL" and Paypal Express Checkout gateway + And the store has a payment method "PayPal" with a code "PAYPAL" and "Paypal Express Checkout" gateway And the store has a product "PHP T-Shirt" priced at "$19.99" And the store ships everywhere for Free And I am logged in as "john@example.com" diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_actions.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_actions.feature deleted file mode 100644 index 6de013563e..0000000000 --- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_actions.feature +++ /dev/null @@ -1,60 +0,0 @@ -@applying_catalog_promotions -Feature: Reapplying catalog promotions after editing their actions - In order to have proper discounts per catalog promotion action - As a Store Owner - I want to have discounts reapplied in product catalog once the action of catalog promotion changes - - Background: - Given the store operates on a channel identified by "Web-US" code - And the store has a "T-Shirt" configurable product - And this product has "PHP T-Shirt" variant priced at "$20.00" in "Web-US" channel - And this product has "Python T-Shirt" variant priced at "$10.00" in "Web-US" channel - And there is a catalog promotion "Winter sale" that reduces price by "50%" and applies on "PHP T-Shirt" variant - And I am logged in as an administrator - - @api @ui @javascript - Scenario: Reapplying catalog promotion after adding a new action to it - Given there is a catalog promotion with "Summer_sale" code and "Summer sale" name - And it applies on "Python T-Shirt" variant - When I modify a catalog promotion "Summer sale" - And I add action that gives "25%" percentage discount - And I save my changes - And the visitor view "Python T-Shirt" variant - Then this product variant price should be "$7.50" - And this product original price should be "$10.00" - - @api @ui @javascript - Scenario: Reapplying catalog promotion after editing its action - When I modify a catalog promotion "Winter sale" - And I edit its action so that it reduces price by "25%" - And I save my changes - And the visitor view "PHP T-Shirt" variant - Then this product variant price should be "$15.00" - And this product original price should be "$20.00" - - @api @ui @javascript - Scenario: Reapplying catalog promotion after removing and adding new action - When I modify a catalog promotion "Winter sale" - And I remove its every action - And I save my changes - And I add action that gives "10%" percentage discount - And I save my changes - And the visitor view "PHP T-Shirt" variant - Then this product variant price should be "$18.00" - And this product original price should be "$20.00" - - @api @ui @javascript - Scenario: Reapplying catalog promotion after adding another action - When I modify a catalog promotion "Winter sale" - And I add another action that gives "10%" percentage discount - And I save my changes - And the visitor view "PHP T-Shirt" variant - Then this product variant price should be "$9.00" - And this product original price should be "$20.00" - - @api @ui @javascript - Scenario: Restoring original price after removing action from catalog promotion configuration - When I modify a catalog promotion "Winter sale" - And I remove its every action - And I save my changes - Then the visitor should see that the "PHP T-Shirt" variant is not discounted diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_scopes.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_scopes.feature deleted file mode 100644 index 9e8adf5730..0000000000 --- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_after_editing_their_scopes.feature +++ /dev/null @@ -1,71 +0,0 @@ -@applying_catalog_promotions -Feature: Reapplying catalog promotion after editing their scopes - In order to have proper discounts per catalog promotion action - As a Store Owner - I want to have catalog promotion reapplied in product catalog once the scope of catalog promotion changes - - Background: - Given the store operates on a single channel in "United States" - And the store classifies its products as "Clothes" and "Dishes" - And the store has a "T-Shirt" configurable product - And this product belongs to "Clothes" - And this product has "PHP T-Shirt" variant priced at "$20.00" - And the store has a "Mug" configurable product - And this product belongs to "Dishes" - And this product has "PHP Mug" variant priced at "$5.00" - And this product has "Expensive Mug" variant priced at "$50.00" - And there is a catalog promotion "Summer sale" that reduces price by "50%" and applies on "PHP T-Shirt" variant - And I am logged in as an administrator - - @api @ui @mink:chromedriver - Scenario: Reapplying catalog promotion after adding a new scope to it - Given there is a catalog promotion named "Mug sale" - When I modify a catalog promotion "Mug sale" - And I add scope that applies on "Expensive Mug" variant and "PHP Mug" variant - And I add action that gives "50%" percentage discount - And I save my changes - Then the visitor should see that the "Expensive Mug" variant is discounted from "$50.00" to "$25.00" with "Mug sale" promotion - And the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$2.50" with "Mug sale" promotion - - @api @ui @javascript - Scenario: Reapplying catalog promotion after removing its scopes - When I modify a catalog promotion "Summer sale" - And I remove its every scope - And I save my changes - Then the visitor should see that the "PHP T-Shirt" variant is not discounted - - @api @ui @mink:chromedriver - Scenario: Reapplying catalog promotion after adding another scope - When I modify a catalog promotion "Summer sale" - And I add another scope that applies on "PHP Mug" variant - And I save my changes - Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$2.50" with "Summer sale" promotion - And the visitor should still see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion - - @api @ui @mink:chromedriver - Scenario: Reapplying catalog promotion after editing the variant in its scope - When I edit "Summer sale" catalog promotion to be applied on "Expensive Mug" variant - Then the visitor should see that the "Expensive Mug" variant is discounted from "$50.00" to "$25.00" with "Summer sale" promotion - And the visitor should see that the "PHP T-Shirt" variant is not discounted - - @api @ui @mink:chromedriver - Scenario: Reapplying catalog promotion after editing the taxon in its scope - Given there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "Clothes" taxon - When I edit "Winter sale" catalog promotion to be applied on "Dishes" taxon - Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$3.50" with "Winter sale" promotion - And the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion - - @api @ui @mink:chromedriver - Scenario: Reapplying catalog promotion after editing the product in its scope - Given there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "T-Shirt" product - When I edit "Winter sale" catalog promotion to be applied on "Mug" product - Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$3.50" with "Winter sale" promotion - And the visitor should see that the "Expensive Mug" variant is discounted from "$50.00" to "$35.00" with "Winter sale" promotion - And the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion - - @api @ui @mink:chromedriver - Scenario: Reapplying catalog promotion after editing the type of its scope - Given there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "PHP T-Shirt" variant - When I edit "Winter sale" catalog promotion to be applied on "Dishes" taxon - Then the visitor should see that the "PHP Mug" variant is discounted from "$5.00" to "$3.50" with "Winter sale" promotion - And the visitor should see that the "PHP T-Shirt" variant is discounted from "$20.00" to "$10.00" with "Summer sale" promotion diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature deleted file mode 100644 index f5d2745ba3..0000000000 --- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variant_once_its_prices_changes.feature +++ /dev/null @@ -1,31 +0,0 @@ -@applying_catalog_promotions -Feature: Reapplying catalog promotions on variant once its prices changes - In order to have proper discounts on variants - As a Store Owner - I want to have discounts reapplied on variant once its prices changes - - Background: - Given the store operates on a channel named "Web-US" with hostname "web-us" - And the store has a "T-Shirt" configurable product - And this product has "PHP T-Shirt" variant priced at "$100.00" in "Web-US" channel - And there is a catalog promotion "Winter sale" available in "Web-US" channel that reduces price by "30%" and applies on "PHP T-Shirt" variant - And there is another catalog promotion "Christmas sale" available in "Web-US" channel that reduces price by "50%" and applies on "PHP T-Shirt" variant - And I am logged in as an administrator - - @api @ui - Scenario: Changing the price of the variant - When I change the price of the "PHP T-Shirt" product variant to "$50.00" in "Web-US" channel - Then the visitor should still see "$35.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should still see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel - - @api @ui - Scenario: Changing the original price of the variant - When I change the original price of the "PHP T-Shirt" product variant to "$50.00" in "Web-US" channel - Then the visitor should see "$17.50" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$50.00" as the original price of the "T-Shirt" product in the "Web-US" channel - - @api @ui - Scenario: Removing the original price of the variant - When I remove the original price of the "PHP T-Shirt" product variant in "Web-US" channel - Then the visitor should see "$12.25" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$35.00" as the original price of the "T-Shirt" product in the "Web-US" channel diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature deleted file mode 100644 index b9b3f3f1e3..0000000000 --- a/features/shop/promotion/applying_catalog_promotions/reapplying_catalog_promotions_on_variants_once_products_taxon_changes.feature +++ /dev/null @@ -1,27 +0,0 @@ -@applying_catalog_promotions -Feature: Reapplying catalog promotions on variants once the product’s taxon changes - In order to have proper discounts in product catalog - As a Store Owner - I want to have discounts reapplied on variants once the product’s taxon changes - - Background: - Given the store operates on a channel named "Web-US" with hostname "web-us" - And the store classifies its products as "Clothes" and "Dishes" - And the store has a "T-Shirt" configurable product - And this product belongs to "Clothes" - And this product has "PHP T-Shirt" variant priced at "$100.00" - And the store has a "Mug" configurable product - And this product has "PHP Mug" variant priced at "$10.00" - And there is a catalog promotion "Winter sale" that reduces price by "30%" and applies on "Clothes" taxon - And there is another catalog promotion "Summer sale" that reduces price by "50%" and applies on "Dishes" taxon - And I am logged in as an administrator - - @api @ui - Scenario: Removing a taxon from a product - When I change that the "T-Shirt" product does not belong to the "Clothes" taxon - Then the visitor should see that the "PHP T-Shirt" variant is not discounted - - @api @ui - Scenario: Adding a taxon to a product - When I assign the "Dishes" taxon to the "Mug" product - Then the visitor should see that the "PHP Mug" variant is discounted from "$10.00" to "$5.00" with "Summer sale" promotion diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_multiple_catalog_promotions_after_editing_their_channels.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_multiple_catalog_promotions_after_editing_their_channels.feature deleted file mode 100644 index 5be099715a..0000000000 --- a/features/shop/promotion/applying_catalog_promotions/reapplying_multiple_catalog_promotions_after_editing_their_channels.feature +++ /dev/null @@ -1,46 +0,0 @@ -@applying_catalog_promotions -Feature: Reapplying multiple catalog promotions after editing their channels - In order to have proper discounts in different channels - As a Store Owner - I want to have discounts reapplied in product catalog once the channels of catalog promotion changes - - Background: - Given the store operates on a channel named "Web-US" with hostname "web-us" - And the store operates on another channel named "Web-GB" with hostname "web-gb" - And the store has a "T-Shirt" configurable product - And this product has "PHP T-Shirt" variant priced at "$100.00" in "Web-US" channel - And "PHP T-Shirt" variant priced at "$100.00" in "Web-GB" channel - And this product is available in "Web-US" channel and "Web-GB" channel - And there is a catalog promotion "Winter sale" available in "Web-US" channel that reduces price by "30%" and applies on "PHP T-Shirt" variant - And there is another catalog promotion "Christmas sale" available in "Web-US" channel and "Web-GB" channel that reduces price by "50%" and applies on "PHP T-Shirt" variant - And I am logged in as an administrator - - @api @ui - Scenario: Removing only modified catalog promotion after removing its channel - When I make the "Winter sale" catalog promotion unavailable in the "Web-US" channel - Then the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel - - @api @ui - Scenario: Reapplying catalog promotion after adding new channel to them - When I make "Winter sale" catalog promotion available in the "Web-GB" channel - Then the visitor should see "$35.00" as the price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should still see "$35.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should still see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel - - @api @ui - Scenario: Reapplying catalog promotion after switching availability in channels - When I switch "Winter sale" catalog promotion availability from the "Web-US" channel to the "Web-GB" channel - Then the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$35.00" as the price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-GB" channel - - @api @ui - Scenario: Reapplying catalog promotion after switching availability in channels - When I make the "Christmas sale" catalog promotion unavailable in the "Web-US" channel - Then the visitor should see "$70.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see "$50.00" as the price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should see "$100.00" as the original price of the "T-Shirt" product in the "Web-GB" channel diff --git a/features/shop/promotion/applying_catalog_promotions/reapplying_single_catalog_promotion_after_editing_its_channels.feature b/features/shop/promotion/applying_catalog_promotions/reapplying_single_catalog_promotion_after_editing_its_channels.feature deleted file mode 100644 index 9a08915c52..0000000000 --- a/features/shop/promotion/applying_catalog_promotions/reapplying_single_catalog_promotion_after_editing_its_channels.feature +++ /dev/null @@ -1,37 +0,0 @@ -@applying_catalog_promotions -Feature: Reapplying single catalog promotion after editing its channels - In order to have proper discounts in different channels - As a Store Owner - I want to have discounts reapplied in product catalog once the channels of catalog promotion changes - - Background: - Given the store operates on a channel named "Web-US" with hostname "web-us" - And the store operates on another channel named "Web-GB" with hostname "web-gb" - And the store has a "T-Shirt" configurable product - And this product has "PHP T-Shirt" variant priced at "$20.00" in "Web-US" channel - And "PHP T-Shirt" variant priced at "$30.00" in "Web-GB" channel - And this product is available in "Web-US" channel and "Web-GB" channel - And there is a catalog promotion "Winter sale" available in "Web-US" channel that reduces price by "30%" and applies on "PHP T-Shirt" variant - And I am logged in as an administrator - - @api @ui - Scenario: Removing applied catalog promotion after removing its channel - When I make this catalog promotion unavailable in the "Web-US" channel - Then the visitor should see "$20.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see this variant is not discounted - - @api @ui - Scenario: Reapplying catalog promotion after adding new channel to them - When I make this catalog promotion available in the "Web-GB" channel - Then the visitor should see "$21.00" as the price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should see "$30.00" as the original price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should still see "$14.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should still see "$20.00" as the original price of the "T-Shirt" product in the "Web-US" channel - - @api @ui - Scenario: Reapplying catalog promotion after switching availability in channels - When I switch this catalog promotion availability from the "Web-US" channel to the "Web-GB" channel - Then the visitor should see "$20.00" as the price of the "T-Shirt" product in the "Web-US" channel - And the visitor should see this variant is not discounted - And the visitor should see "$21.00" as the price of the "T-Shirt" product in the "Web-GB" channel - And the visitor should see "$30.00" as the original price of the "T-Shirt" product in the "Web-GB" channel diff --git a/package.json b/package.json index cb27498202..4d95e26cc5 100644 --- a/package.json +++ b/package.json @@ -14,20 +14,25 @@ "watch": "encore dev --watch" }, "dependencies": { + "@sylius-ui/admin": "file:src/Sylius/Bundle/AdminBundle", "chart.js": "^3.7.1", "jquery": "^3.5.0", "jquery.dirtyforms": "^2.0.0", "lightbox2": "^2.9.0", "semantic-ui-css": "^2.2.0", - "slick-carousel": "^1.8.1" + "slick-carousel": "^1.8.1", + "@symfony/ux-autocomplete": "file:vendor/symfony/ux-autocomplete/assets", + "@symfony/ux-live-component": "file:vendor/symfony/ux-live-component/assets" }, "devDependencies": { "@babel/core": "^7.0.0", - "@babel/polyfill": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/polyfill": "^7.0.0", "@babel/preset-env": "^7.18.10", "@babel/register": "^7.0.0", + "@hotwired/stimulus": "^3.0.0", "@semantic-ui-react/css-patch": "^1.1.2", + "@symfony/stimulus-bridge": "^3.2.2", "@symfony/webpack-encore": "^3.1.0", "eslint": "^8.23.0", "eslint-config-airbnb-base": "^15.0.0", @@ -35,6 +40,7 @@ "eslint-plugin-import": "^2.26.0", "sass": "^1.54.8", "sass-loader": "^13.0.0", + "tom-select": "^2.2.2", "yargs": "^17.5.1" }, "engines": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4d253a07ea..f85742315a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -25,11 +25,6 @@ parameters: count: 1 path: src/Sylius/Bundle/AddressingBundle/Form/Type/ProvinceCodeChoiceType.php - - - message: "#^Method Sylius\\\\Bundle\\\\AddressingBundle\\\\Form\\\\Type\\\\ZoneChoiceType\\:\\:__construct\\(\\) has parameter \\$scopeTypes with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/AddressingBundle/Form/Type/ZoneChoiceType.php - - message: "#^Method Sylius\\\\Bundle\\\\AddressingBundle\\\\Form\\\\Type\\\\ZoneChoiceType\\:\\:__construct\\(\\) has parameter \\$zoneRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#" count: 1 @@ -2405,11 +2400,6 @@ parameters: count: 1 path: src/Sylius/Bundle/CoreBundle/Collector/SyliusCollector.php - - - message: "#^If condition is always false\\.$#" - count: 1 - path: src/Sylius/Bundle/CoreBundle/Command/AbstractInstallCommand.php - - message: "#^If condition is always false\\.$#" count: 1 @@ -3575,11 +3565,6 @@ parameters: count: 1 path: src/Sylius/Bundle/CoreBundle/Form/EventSubscriber/CustomerRegistrationFormSubscriber.php - - - message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Form\\\\Extension\\\\CountryTypeExtension\\:\\:__construct\\(\\) has parameter \\$countryRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#" - count: 1 - path: src/Sylius/Bundle/CoreBundle/Form/Extension/CountryTypeExtension.php - - message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Form\\\\Extension\\\\LocaleTypeExtension\\:\\:__construct\\(\\) has parameter \\$localeRepository with generic interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface but does not specify its types\\: T$#" count: 1 @@ -3795,11 +3780,6 @@ parameters: count: 1 path: src/Sylius/Bundle/CoreBundle/MessageHandler/Admin/Account/RequestResetPasswordEmailHandler.php - - - message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\MessageHandler\\\\Admin\\\\Account\\\\SendResetPasswordEmailHandler\\:\\:__construct\\(\\) has parameter \\$userRepository with generic interface Sylius\\\\Component\\\\User\\\\Repository\\\\UserRepositoryInterface but does not specify its types\\: T$#" - count: 1 - path: src/Sylius/Bundle/CoreBundle/MessageHandler/Admin/Account/SendResetPasswordEmailHandler.php - - message: "#^Method Sylius\\\\Bundle\\\\CoreBundle\\\\Migrations\\\\Version20171003103916\\:\\:getProductAttributes\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -4125,11 +4105,6 @@ parameters: count: 1 path: src/Sylius/Bundle/LocaleBundle/SyliusLocaleBundle.php - - - message: "#^If condition is always false\\.$#" - count: 1 - path: src/Sylius/Bundle/OrderBundle/Command/RemoveExpiredCartsCommand.php - - message: "#^Method Sylius\\\\Bundle\\\\OrderBundle\\\\Context\\\\SessionBasedCartContext\\:\\:__construct\\(\\) has parameter \\$orderRepository with generic interface Sylius\\\\Component\\\\Order\\\\Repository\\\\OrderRepositoryInterface but does not specify its types\\: T$#" count: 1 @@ -4850,51 +4825,6 @@ parameters: count: 1 path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockDataCollector.php - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:getRenderedEvents\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:startRenderingBlock\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:startRenderingEvent\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:startRenderingEvent\\(\\) has parameter \\$eventNames with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:stopRenderingBlock\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:stopRenderingEvent\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TemplateBlockRenderingHistory\\:\\:stopRenderingEvent\\(\\) has parameter \\$eventNames with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TraceableTemplateBlockRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateBlockRenderer.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DataCollector\\\\TraceableTemplateEventRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateEventRenderer.php - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\DependencyInjection\\\\SyliusUiExtension\\:\\:loadEvents\\(\\) has parameter \\$eventsConfig with no value type specified in iterable type array\\.$#" count: 1 @@ -4905,56 +4835,6 @@ parameters: count: 1 path: src/Sylius/Bundle/UiBundle/DependencyInjection/SyliusUiExtension.php - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Registry\\\\TemplateBlock\\:\\:__construct\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Registry\\\\TemplateBlock\\:\\:getContext\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Registry\\\\TemplateBlockRegistry\\:\\:__construct\\(\\) has parameter \\$eventsToTemplateBlocks with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistry.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\DelegatingTemplateEventRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/DelegatingTemplateEventRenderer.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\HtmlDebugTemplateBlockRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateBlockRenderer.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\HtmlDebugTemplateEventRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateEventRenderer.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TemplateBlockRendererInterface\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/TemplateBlockRendererInterface.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TemplateEventRendererInterface\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/TemplateEventRendererInterface.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TwigTemplateBlockRenderer\\:\\:__construct\\(\\) has parameter \\$contextProviders with no value type specified in iterable type iterable\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php - - - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Renderer\\\\TwigTemplateBlockRenderer\\:\\:render\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php - - message: "#^Method Sylius\\\\Bundle\\\\UiBundle\\\\Storage\\\\FilterStorage\\:\\:all\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 @@ -5985,26 +5865,6 @@ parameters: count: 1 path: src/Sylius/Component/Core/Provider/ProductVariantMap/ProductVariantsMapProviderInterface.php - - - message: "#^Method Sylius\\\\Component\\\\Core\\\\Provider\\\\ProductVariantsPricesProvider\\:\\:constructOptionsMap\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProvider.php - - - - message: "#^Method Sylius\\\\Component\\\\Core\\\\Provider\\\\ProductVariantsPricesProvider\\:\\:provideVariantsPrices\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProvider.php - - - - message: "#^PHPDoc tag @var for variable \\$appliedPromotions contains generic class Doctrine\\\\Common\\\\Collections\\\\ArrayCollection but does not specify its types\\: TKey, T$#" - count: 1 - path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProvider.php - - - - message: "#^Method Sylius\\\\Component\\\\Core\\\\Provider\\\\ProductVariantsPricesProviderInterface\\:\\:provideVariantsPrices\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/Sylius/Component/Core/Provider/ProductVariantsPricesProviderInterface.php - - message: "#^Method Sylius\\\\Component\\\\Core\\\\Repository\\\\OrderItemRepositoryInterface\\:\\:findOneByIdAndCustomer\\(\\) has parameter \\$id with no type specified\\.$#" count: 1 diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 2bce4c7ad0..96f9de35b8 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -37,6 +37,9 @@ parameters: # Temporary exclusion during upgrade to API Platform 3 - 'src/Sylius/Bundle/ApiBundle/**.php' + # Random errors related to Template Events (we're going to replace them with Twig Events anyway) + - 'src/Sylius/Bundle/UiBundle/Console/Command/DebugTemplateEventCommand.php' + ignoreErrors: - '/(Interface|Class) [a-zA-Z\\]+ specifies template type (\w+) of interface [a-zA-Z\\]+ as [a-zA-Z\\]+ (of [a-zA-Z\\]+ )?but it''s already specified as/' # turns off a weird generics check behavior, we are basing on Psalm for generics checks - '/Access to an undefined property Doctrine\\Common\\Collections\\ArrayCollection/' @@ -48,3 +51,4 @@ parameters: - '/Method Sylius\\Component\\(\w+)\\Model\\(\w+)\:\:getId\(\) has no return type specified./' - '/Method [a-zA-z\\]+Filter\:\:filterProperty\(\) has parameter \$value with no type specified./' - '/Method [a-zA-z\\]+Persister\:\:(persist|remove|supports)\(\) has parameter \$data with no type specified./' + - '/Method Sylius\\Bundle\\AdminBundle\\Twig\\Component\\[a-zA-Z\\]+\:\:getDataModelValue\(\) is unused./' diff --git a/rector.php b/rector.php index 6f399dadbd..47f27d17ab 100644 --- a/rector.php +++ b/rector.php @@ -2,21 +2,12 @@ declare(strict_types=1); -use Rector\Core\Configuration\Option; -use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector; -use Rector\Php74\Rector\Property\TypedPropertyRector; +use Rector\Config\RectorConfig; use Rector\Set\ValueObject\LevelSetList; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -return static function (ContainerConfigurator $containerConfigurator): void +return static function (RectorConfig $config): void { - $containerConfigurator->import(LevelSetList::UP_TO_PHP_80); - - $parameters = $containerConfigurator->parameters(); - $parameters->set(Option::AUTO_IMPORT_NAMES, true); - $parameters->set(Option::IMPORT_SHORT_CLASSES, false); - - $services = $containerConfigurator->services(); - $services->set(TypedPropertyRector::class); - $services->set(ClosureToArrowFunctionRector::class); + $config->sets([ + LevelSetList::UP_TO_PHP_82 + ]); }; diff --git a/src/Sylius/Behat/Client/ResponseChecker.php b/src/Sylius/Behat/Client/ResponseChecker.php index b1588ec869..789325d4c9 100644 --- a/src/Sylius/Behat/Client/ResponseChecker.php +++ b/src/Sylius/Behat/Client/ResponseChecker.php @@ -108,14 +108,12 @@ final class ResponseChecker implements ResponseCheckerInterface return $response->getStatusCode() === Response::HTTP_OK; } - /** @param string|int $value */ - public function hasValue(Response $response, string $key, $value): bool + public function hasValue(Response $response, string $key, bool|int|string|null $value): bool { return $this->getResponseContentValue($response, $key) === $value; } - /** @param string|int $value */ - public function hasValueInCollection(Response $response, string $key, $value): bool + public function hasValueInCollection(Response $response, string $key, bool|int|string $value): bool { return in_array($value, $this->getResponseContentValue($response, $key), true); } @@ -176,6 +174,15 @@ final class ResponseChecker implements ResponseCheckerInterface return true; } + public function hasValueInSubresourceObject(Response $response, string $subResource, string $key, bool|int|string $expectedValue): bool + { + $resource = $this->getResponseContentValue($response, $subResource); + + $this->assertIsArray($resource); + + return $resource[$key] === $expectedValue; + } + /** @param string|array $value */ public function hasItemOnPositionWithValue(Response $response, int $position, string $key, $value): bool { diff --git a/src/Sylius/Behat/Client/ResponseCheckerInterface.php b/src/Sylius/Behat/Client/ResponseCheckerInterface.php index b775005011..7397a8b4d2 100644 --- a/src/Sylius/Behat/Client/ResponseCheckerInterface.php +++ b/src/Sylius/Behat/Client/ResponseCheckerInterface.php @@ -45,7 +45,7 @@ interface ResponseCheckerInterface public function hasCollection(Response $response): bool; - public function hasValue(Response $response, string $key, int|string $value): bool; + public function hasValue(Response $response, string $key, bool|int|string|null $value): bool; public function hasValueInCollection(Response $response, string $key, int|string $value): bool; @@ -65,6 +65,13 @@ interface ResponseCheckerInterface array $expectedValues, ): bool; + public function hasValueInSubresourceObject( + Response $response, + string $subResource, + string $key, + bool|int|string $expectedValue, + ): bool; + public function hasItemOnPositionWithValue(Response $response, int $position, string $key, array|string $value): bool; public function hasItemWithTranslation(Response $response, string $locale, string $key, string $translation): bool; diff --git a/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php b/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php index a73e2a6415..4de59d412a 100644 --- a/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/BrowsingProductVariantsContext.php @@ -51,9 +51,9 @@ final class BrowsingProductVariantsContext implements Context } /** - * @When I save my new configuration + * @When I save my new elements order */ - public function iSaveMyNewConfiguration(): void + public function iSaveMyNewElementsOrder(): void { $this->client->update(); } diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php index 945d287759..34a29a2cd0 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingCatalogPromotionsContext.php @@ -272,13 +272,16 @@ final readonly class ManagingCatalogPromotionsContext implements Context } /** - * @When I remove its every action + * @When I remove its last action */ - public function iRemoveItsEveryAction(): void + public function iRemoveItsLastAction(): void { $content = $this->client->getContent(); - $content['actions'] = []; - $this->client->setRequestData($content); + $lastKey = array_key_last($content['actions']); + if (null !== $lastKey) { + unset($content['actions'][$lastKey]); + $this->client->setRequestData($content); + } } /** @@ -469,15 +472,41 @@ final readonly class ManagingCatalogPromotionsContext implements Context } /** - * @When I remove its every scope + * @When I remove its last scope */ - public function iRemoveItsEveryScope(): void + public function iRemoveItsLastScope(): void { $content = $this->client->getContent(); - $content['scopes'] = []; + $lastKey = array_key_last($content['scopes']); + if (null !== $lastKey) { + unset($content['scopes'][$lastKey]); + $this->client->setRequestData($content); + } + } + + /** + * @When I add :productVariant variant to its scope + */ + public function iAddVariantToItsScope(ProductVariantInterface $productVariant): void + { + $content = $this->client->getContent(); + $content['scopes'][0]['configuration']['variants'][] = $productVariant->getCode(); $this->client->setRequestData($content); } + /** + * @When I remove :productVariant variant from its scope + */ + public function iRemoveVariantFromItsScope(ProductVariantInterface $productVariant): void + { + $content = $this->client->getContent(); + $key = array_search($productVariant->getCode(), $content['scopes'][0]['configuration']['variants'] ?? []); + if (false !== $key) { + unset($content['scopes'][0]['configuration']['variants'][$key]); + $this->client->setRequestData($content); + } + } + /** * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" variant)$/ */ @@ -485,6 +514,16 @@ final readonly class ManagingCatalogPromotionsContext implements Context CatalogPromotionInterface $catalogPromotion, ProductVariantInterface $productVariant, ): void { + $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode()); + + $content = $this->client->getContent(); + unset($content['scopes'][0]); + $content['scopes'][0]['type'] = $type; + $content['scopes'][0]['configuration'] = $configuration; + + $this->client->setRequestData($content); + + $this->client->update(); $this->changeFirstScopeConfigurationTo( $catalogPromotion, InForVariantsScopeVariantChecker::TYPE, @@ -492,34 +531,6 @@ final readonly class ManagingCatalogPromotionsContext implements Context ); } - /** - * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" taxon)$/ - */ - public function iEditCatalogPromotionToBeAppliedOnTaxon( - CatalogPromotionInterface $catalogPromotion, - TaxonInterface $taxon, - ): void { - $this->changeFirstScopeConfigurationTo( - $catalogPromotion, - InForTaxonsScopeVariantChecker::TYPE, - ['taxons' => [$taxon->getCode()]], - ); - } - - /** - * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" product)$/ - */ - public function iEditCatalogPromotionToBeAppliedOnProduct( - CatalogPromotionInterface $catalogPromotion, - ProductInterface $product, - ): void { - $this->changeFirstScopeConfigurationTo( - $catalogPromotion, - InForProductScopeVariantChecker::TYPE, - ['products' => [$product->getCode()]], - ); - } - /** * @When I disable :catalogPromotion catalog promotion */ @@ -536,43 +547,6 @@ final readonly class ManagingCatalogPromotionsContext implements Context $this->toggleCatalogPromotion($catalogPromotion, true); } - /** - * @When /^I edit ("[^"]+" catalog promotion) to have ("[^"]+") discount$/ - */ - public function iEditCatalogPromotionToHaveDiscount(CatalogPromotionInterface $catalogPromotion, float $amount): void - { - $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode()); - $scopes = [[ - 'type' => PercentageDiscountPriceCalculator::TYPE, - 'configuration' => [ - 'amount' => $amount, - ], - ]]; - - $this->client->updateRequestData(['actions' => $scopes]); - $this->client->update(); - } - - /** - * @When /^I edit ("[^"]+" catalog promotion) to have ("[^"]+") of fixed discount in the ("[^"]+" channel)$/ - */ - public function iEditCatalogPromotionToHaveFixedDiscountInTheChannel( - CatalogPromotionInterface $catalogPromotion, - int $amount, - ChannelInterface $channel, - ): void { - $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode()); - $content = $this->client->getContent(); - - $content['actions'] = [[ - 'type' => FixedDiscountPriceCalculator::TYPE, - 'configuration' => [$channel->getCode() => ['amount' => $amount]], - ]]; - - $this->client->setRequestData($content); - $this->client->update(); - } - /** * @When /^I edit it to have ("[^"]+") of fixed discount in the ("[^"]+" channel)$/ */ @@ -1425,7 +1399,8 @@ final readonly class ManagingCatalogPromotionsContext implements Context } /** - * @Then I should be notified that the fixed amount should be a number and cannot be empty + * @Then I should be notified that the fixed amount should be a number + * @Then I should be notified that the fixed amount cannot be empty */ public function iShouldBeNotifiedThatTheFixedAmountShouldBeANumber(): void { @@ -1613,23 +1588,6 @@ final readonly class ManagingCatalogPromotionsContext implements Context $this->sharedStorage->set('catalog_promotion', $catalogPromotion); } - private function changeFirstScopeConfigurationTo( - CatalogPromotionInterface $catalogPromotion, - string $type, - array $configuration, - ): void { - $this->client->buildUpdateRequest(Resources::CATALOG_PROMOTIONS, $catalogPromotion->getCode()); - - $content = $this->client->getContent(); - unset($content['scopes'][0]); - $content['scopes'][0]['type'] = $type; - $content['scopes'][0]['configuration'] = $configuration; - - $this->client->setRequestData($content); - - $this->client->update(); - } - private function createCatalogPromotion( string $name, int $priority, diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php index 6aa9c10f96..ff4562dea6 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingCountriesContext.php @@ -387,7 +387,7 @@ final class ManagingCountriesContext implements Context { Assert::contains( $this->responseChecker->getError($this->client->getLastResponse()), - 'Cannot delete, the province is in use.', + 'Cannot delete, the Province is in use.', ); } diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php index 612b1b9ab0..5c2e3b4e43 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentMethodsContext.php @@ -20,13 +20,14 @@ use Sylius\Behat\Context\Api\Admin\Helper\ValidationTrait; use Sylius\Behat\Context\Api\Resources; use Sylius\Behat\Service\Converter\SectionAwareIriConverter; use Sylius\Behat\Service\SharedStorageInterface; +use Sylius\Component\Core\Formatter\StringInflector; use Sylius\Component\Core\Model\AdminUserInterface; use Sylius\Component\Core\Model\ChannelInterface; -use Sylius\Component\Payment\Model\PaymentMethodInterface; +use Sylius\Component\Core\Model\PaymentMethodInterface; use Symfony\Component\HttpFoundation\Request as HttpRequest; use Webmozart\Assert\Assert; -final class ManagingPaymentMethodsContext implements Context +final readonly class ManagingPaymentMethodsContext implements Context { use ValidationTrait; @@ -48,6 +49,43 @@ final class ManagingPaymentMethodsContext implements Context $this->client->buildUpdateRequest(Resources::PAYMENT_METHODS, $paymentMethod->getCode()); } + /** + * @When /^I set its "Username" as "([^"]+)", "Password" as "([^"]+)" and "Signature" as "([^"]+)"$/ + */ + public function iSetItsUsernameAsPasswordAsAndSignatureAs(string $username, string $password, string $signature): void + { + $this->updateGatewayConfig([ + 'username' => $username, + 'password' => $password, + 'signature' => $signature, + ]); + } + + /** + * @When /^I set its "Publishable key" as "([^"]+)" and "Secret key" as "([^"]+)"$/ + */ + public function iSetItsPublishableKeyAsAndSecretKeyAs(string $publishableKey, string $secretKey): void + { + $this->updateGatewayConfig([ + 'publishable_key' => $publishableKey, + 'secret_key' => $secretKey, + ]); + } + + /** + * @When I update its :field with :value + */ + public function iUpdateItsWith(string $field, string $value): void + { + $availableFields = ['Publishable key', 'Secret key', 'Username', 'Password', 'Signature', 'Sandbox']; + + if (!in_array($field, $availableFields)) { + throw new \InvalidArgumentException(sprintf('There is no configuration for "%s" field.', $field)); + } + + $this->updateGatewayConfig([StringInflector::nameToLowercaseCode($field) => $value]); + } + /** * @When I name it :name in :localeCode * @When I rename it to :name in :localeCode @@ -58,6 +96,14 @@ final class ManagingPaymentMethodsContext implements Context $this->client->addRequestData('translations', [$localeCode => ['name' => $name]]); } + /** + * @When I enable sandbox mode + */ + public function iEnableSandboxMode(): void + { + $this->client->addRequestData('gatewayConfig', ['config' => ['sandbox' => true]]); + } + /** * @When I do not name it */ @@ -184,14 +230,6 @@ final class ManagingPaymentMethodsContext implements Context $this->client->create(); } - /** - * @When I cancel my changes - */ - public function iCancelMyChanges(): void - { - $this->createPage->cancelChanges(); - } - /** * @When I start sorting payment methods by name * @When the payment methods are already sorted by name @@ -380,7 +418,7 @@ final class ManagingPaymentMethodsContext implements Context { $response = $this->client->index(Resources::PAYMENT_METHODS); - if ($field = 'name') { + if ($field === 'Name') { $paymentMethods = $this->responseChecker->getCollection($response); Assert::same(end($paymentMethods)['translations']['en_US']['name'], $value); @@ -465,9 +503,11 @@ final class ManagingPaymentMethodsContext implements Context */ public function iShouldBeNotifiedThatIHaveToSpecifyStripe(string $element): void { + $element = strtolower($element); + Assert::same( $this->responseChecker->getError($this->client->getLastResponse()), - sprintf('gatewayConfig.config[%s]: Please enter stripe %s.', str_replace(' ', '_', strtolower($element)), $element), + sprintf('gatewayConfig.config[%s]: Please enter stripe %s.', str_replace(' ', '_', $element), $element), ); } @@ -674,13 +714,13 @@ final class ManagingPaymentMethodsContext implements Context } /** - * @Then this payment method :element should be :value + * @Then /^this payment method "([^"]+)" should be "([^"]+)"$/ */ public function thisPaymentMethodElementShouldBe( string $element, string $value, ): void { - if ($element === 'name') { + if ($element === 'Name') { Assert::inArray( $value, $this->getPaymentMethodNamesFromCollection(), @@ -696,6 +736,36 @@ final class ManagingPaymentMethodsContext implements Context ); } + /** + * @Then /^its gateway configuration "([^"]+)" should be "([^"]+)"$/ + */ + public function itsGatewayConfigurationShouldBe(string $element, string $value): void + { + if (!$this->sharedStorage->has('gateway_config_iri')) { + $this->sharedStorage->set('gateway_config_iri', $this->responseChecker->getValue($this->client->getLastResponse(), 'gatewayConfig')); + } + + $response = $this->client->showByIri($this->sharedStorage->get('gateway_config_iri')); + + Assert::true( + $this->responseChecker->hasValueInSubresourceObject($response, 'config', StringInflector::nameToLowercaseCode($element), $value), + sprintf('Gateway configuration should have %s "%s", but it does not', $element, $value), + ); + } + + /** + * @Then this payment method should be in sandbox mode + */ + public function thisPaymentMethodShouldBeInSandboxMode(): void + { + $response = $this->client->showByIri($this->sharedStorage->get('gateway_config_iri')); + + Assert::true( + $this->responseChecker->hasValueInSubresourceObject($response, 'config', 'sandbox', true), + 'Gateway configuration should be in sandbox mode, but it is not', + ); + } + /** * @Then I should be notified that it has been successfully created */ @@ -761,6 +831,9 @@ final class ManagingPaymentMethodsContext implements Context return $this->responseChecker->getValue($response, 'localeCode'); } + /** + * @param array $paymentMethod + */ private function getFieldValueOfFirstPaymentMethod(array $paymentMethod, string $field): ?string { if ($field === 'code') { @@ -774,10 +847,34 @@ final class ManagingPaymentMethodsContext implements Context return null; } + /** + * @return string[] + */ private function getPaymentMethodNamesFromCollection(): array { $paymentMethods = $this->responseChecker->getCollection($this->client->index(Resources::PAYMENT_METHODS)); return array_map(fn (array $paymentMethod) => $paymentMethod['translations']['en_US']['name'], $paymentMethods); } + + /** + * @param array $config + */ + private function updateGatewayConfig(array $config): void + { + /** @var PaymentMethodInterface $paymentMethod */ + $paymentMethod = $this->sharedStorage->get('payment_method'); + $gatewayConfigurationIri = $this->sectionAwareIriConverter->getIriFromResourceInSection( + $paymentMethod->getGatewayConfig(), + 'admin', + ); + + $this->client->addRequestData( + 'gatewayConfig', + [ + '@id' => $gatewayConfigurationIri, + 'config' => $config, + ], + ); + } } diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php index f7166c8a36..cfab91b005 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingProductsContext.php @@ -320,6 +320,7 @@ final class ManagingProductsContext implements Context * @When I set its :attribute attribute to :value * @When I set its :attribute attribute to :value in :localeCode * @When I do not set its :attribute attribute in :localeCode + * @When I set the :attribute attribute value to :value in :localeCode */ public function iSetItsAttributeTo( ProductAttributeInterface $attribute, @@ -355,6 +356,7 @@ final class ManagingProductsContext implements Context /** * @When I add the :attributeName attribute + * @When I add the :attributeName attribute to it */ public function iAddTheAttribute(string $attributeName): void { diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php index 7e97d2ddfb..f96533cfa6 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingPromotionsContext.php @@ -321,25 +321,27 @@ final class ManagingPromotionsContext implements Context } /** - * @When I specify that this action should be applied to items from :taxon category + * @When I specify that this action should be applied to items from :taxon category for :channel channel */ - public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(TaxonInterface $taxon): void - { + public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory( + TaxonInterface $taxon, + ChannelInterface $channel, + ): void { $actions = $this->getActions(); - $channelCode = key($actions[0]['configuration']); - $actions[0]['configuration'][$channelCode]['filters']['taxons_filter']['taxons'] = [$taxon->getCode()]; + $actions[0]['configuration'][$channel->getCode()]['filters']['taxons_filter']['taxons'] = [$taxon->getCode()]; $this->client->addRequestData('actions', $actions); } /** - * @When I specify that this action should be applied to the :product product + * @When I specify that this action should be applied to the :product product for :channel channel */ - public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(ProductInterface $product): void - { + public function iSpecifyThatThisActionShouldBeAppliedToTheProduct( + ProductInterface $product, + ChannelInterface $channel, + ): void { $actions = $this->getActions(); - $channelCode = key($actions[0]['configuration']); - $actions[0]['configuration'][$channelCode]['filters']['products_filter']['products'] = [$product->getCode()]; + $actions[0]['configuration'][$channel->getCode()]['filters']['products_filter']['products'] = [$product->getCode()]; $this->client->addRequestData('actions', $actions); } @@ -562,6 +564,15 @@ final class ManagingPromotionsContext implements Context ); } + /** + * @Then the :promotionName promotion should be successfully created + */ + public function thePromotionShouldBeSuccessfullyCreated(string $promotionName): void + { + $this->iShouldBeNotifiedThatItHasBeenSuccessfullyCreated(); + $this->thePromotionShouldAppearInTheRegistry($promotionName); + } + /** * @Then I should be notified that it has been successfully created */ diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php index 3f0a405178..6842b6049e 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingShippingMethodsContext.php @@ -403,8 +403,9 @@ final class ManagingShippingMethodsContext implements Context } /** - * @Then the shipping method :name should be in the registry - * @Then the shipping method :name should appear in the registry + * @Then the shipping method :shippingMethod should be in the registry + * @Then the shipping method :shippingMethod should appear in the registry + * @Then the :shippingMethod shipping method should be successfully created */ public function theShippingMethodShouldAppearInTheRegistry(string $name): void { diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php index a9171d3437..9d6bd6fc53 100644 --- a/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php +++ b/src/Sylius/Behat/Context/Api/Admin/ManagingZonesContext.php @@ -232,9 +232,9 @@ final class ManagingZonesContext implements Context } /** - * @Then I can not add a zone :zone + * @Then /^I should not be able to add the ("[^"]+" zone) as a member$/ */ - public function iCanNotAddAZone(ZoneInterface $zone): void + public function iShouldNotBeAbleToAddZoneAsAMember(ZoneInterface $zone): void { $this->client->addSubResourceData('members', [ 'code' => $zone->getCode(), diff --git a/src/Sylius/Behat/Context/Setup/CustomerContext.php b/src/Sylius/Behat/Context/Setup/CustomerContext.php index fbb40b2e72..5efa3a296a 100644 --- a/src/Sylius/Behat/Context/Setup/CustomerContext.php +++ b/src/Sylius/Behat/Context/Setup/CustomerContext.php @@ -111,6 +111,7 @@ final class CustomerContext implements Context /** * @Given there is a customer :name with an email :email + * @Given there is also a customer :name with an email :email */ public function theStoreHasCustomerAccountWithEmailAndName(string $name, string $email): void { diff --git a/src/Sylius/Behat/Context/Setup/PaymentContext.php b/src/Sylius/Behat/Context/Setup/PaymentContext.php index e1f89a97aa..c072b2f1b9 100644 --- a/src/Sylius/Behat/Context/Setup/PaymentContext.php +++ b/src/Sylius/Behat/Context/Setup/PaymentContext.php @@ -26,8 +26,14 @@ use Sylius\Component\Payment\Repository\PaymentMethodRepositoryInterface; use Sylius\Component\Resource\Factory\FactoryInterface; use Webmozart\Assert\Assert; -final class PaymentContext implements Context +final readonly class PaymentContext implements Context { + /** + * @param PaymentMethodRepositoryInterface $paymentMethodRepository + * @param ExampleFactoryInterface $paymentMethodExampleFactory + * @param FactoryInterface $paymentMethodTranslationFactory + * @param array $gatewayFactories + */ public function __construct( private SharedStorageInterface $sharedStorage, private PaymentMethodRepositoryInterface $paymentMethodRepository, @@ -42,7 +48,7 @@ final class PaymentContext implements Context * @Given the store (also )allows paying (with ):paymentMethodName * @Given the store (also )allows paying with :paymentMethodName at position :position */ - public function storeAllowsPaying($paymentMethodName, $position = null) + public function storeAllowsPaying(string $paymentMethodName, ?int $position = null): void { $this->createPaymentMethod($paymentMethodName, 'PM_' . StringInflector::nameToCode($paymentMethodName), 'Offline', 'Payment method', true, $position); } @@ -77,28 +83,32 @@ final class PaymentContext implements Context /** * @Given the store has (also) a payment method :paymentMethodName with a code :paymentMethodCode */ - public function theStoreHasAPaymentMethodWithACode($paymentMethodName, $paymentMethodCode) + public function theStoreHasAPaymentMethodWithACode(string $paymentMethodName, string $paymentMethodCode): void { $this->createPaymentMethod($paymentMethodName, $paymentMethodCode, 'Offline'); } /** - * @Given the store has (also) a payment method :paymentMethodName with a code :paymentMethodCode and Paypal Express Checkout gateway + * @Given /^the store has(?:| also) a payment method "([^"]+)" with a code "([^"]+)" and "([^"]+)" gateway$/ */ - public function theStoreHasPaymentMethodWithCodeAndPaypalExpressCheckoutGateway( - $paymentMethodName, - $paymentMethodCode, - ) { - $paymentMethod = $this->createPaymentMethod($paymentMethodName, $paymentMethodCode, 'Paypal Express Checkout'); - $paymentMethod->getGatewayConfig()->setConfig([ - 'username' => 'TEST', - 'password' => 'TEST', - 'signature' => 'TEST', - 'payum.http_client' => '@sylius.payum.http_client', - 'sandbox' => true, - ]); + public function theStoreHasPaymentMethodWithCodeAndGateway( + string $paymentMethodName, + string $paymentMethodCode, + string $gatewayFactory, + ): void { + $paymentMethod = $this->createPaymentMethod($paymentMethodName, $paymentMethodCode, $gatewayFactory); + + match ($gatewayFactory) { + 'Paypal Express Checkout' => $this->configurePaypalExpressCheckoutGateway($paymentMethod), + 'Stripe Checkout' => $this->configureStripeCheckoutGateway($paymentMethod), + default => throw new \InvalidArgumentException( + sprintf('Gateway factory "%s" is not supported. Available options are: %s', $gatewayFactory, implode(', ', $this->gatewayFactories)), + ), + }; $this->paymentMethodManager->flush(); + + $this->sharedStorage->set('payment_method', $paymentMethod); } /** @@ -184,24 +194,14 @@ final class PaymentContext implements Context Assert::eq($payment->getState(), $state); } - /** - * @param string $name - * @param string $code - * @param string $gatewayFactory - * @param string $description - * @param bool $addForCurrentChannel - * @param int|null $position - * - * @return PaymentMethodInterface - */ private function createPaymentMethod( - $name, - $code, - $gatewayFactory = 'Offline', - $description = '', - $addForCurrentChannel = true, - $position = null, - ) { + string $name, + string $code, + string $gatewayFactory, + string $description = '', + bool $addForCurrentChannel = true, + ?int $position = null, + ): PaymentMethodInterface { $gatewayFactory = array_search($gatewayFactory, $this->gatewayFactories); /** @var PaymentMethodInterface $paymentMethod */ @@ -216,7 +216,7 @@ final class PaymentContext implements Context ]); if (null !== $position) { - $paymentMethod->setPosition((int) $position); + $paymentMethod->setPosition($position); } $this->sharedStorage->set('payment_method', $paymentMethod); @@ -224,4 +224,23 @@ final class PaymentContext implements Context return $paymentMethod; } + + private function configurePaypalExpressCheckoutGateway(PaymentMethodInterface $paymentMethod): void + { + $paymentMethod->getGatewayConfig()->setConfig([ + 'username' => 'TEST', + 'password' => 'TEST', + 'signature' => 'TEST', + 'payum.http_client' => '@sylius.payum.http_client', + 'sandbox' => true, + ]); + } + + private function configureStripeCheckoutGateway(PaymentMethodInterface $paymentMethod): void + { + $paymentMethod->getGatewayConfig()->setConfig([ + 'publishable_key' => 'TEST', + 'secret_key' => 'TEST', + ]); + } } diff --git a/src/Sylius/Behat/Context/Transform/ProductContext.php b/src/Sylius/Behat/Context/Transform/ProductContext.php index 8a54570486..b93118df7f 100644 --- a/src/Sylius/Behat/Context/Transform/ProductContext.php +++ b/src/Sylius/Behat/Context/Transform/ProductContext.php @@ -30,6 +30,8 @@ final class ProductContext implements Context * @Transform /^"([^"]+)" product(?:|s)$/ * @Transform /^(?:a|an) "([^"]+)"$/ * @Transform :product + * @Transform :firstProduct + * @Transform :secondProduct */ public function getProductByName($productName) { diff --git a/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php b/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php index d1cf8ce07a..64b2403467 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/BrowsingProductVariantsContext.php @@ -133,24 +133,24 @@ final class BrowsingProductVariantsContext implements Context /** * @Then /^the variant "([^"]+)" should have (\d+) items on hand$/ */ - public function thisVariantShouldHaveItemsOnHand($productVariantName, $quantity) + public function thisVariantShouldHaveItemsOnHand($productVariantName, $quantity): void { Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage( ['name' => $productVariantName], - sprintf('td > div.ui.label:contains("%s")', $quantity), + sprintf('[data-test-on-hand]:contains("%s")', $quantity), )); } /** * @Then /^the "([^"]+)" variant of ("[^"]+" product) should have (\d+) items on hand$/ */ - public function theVariantOfProductShouldHaveItemsOnHand($productVariantName, ProductInterface $product, $quantity) + public function theVariantOfProductShouldHaveItemsOnHand($productVariantName, ProductInterface $product, $quantity): void { $this->indexPage->open(['productId' => $product->getId()]); Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage( ['name' => $productVariantName], - sprintf('td > div.ui.label:contains("%s")', $quantity), + sprintf('[data-test-on-hand]:contains("%s")', $quantity), )); } @@ -268,10 +268,10 @@ final class BrowsingProductVariantsContext implements Context */ public function iShouldSeeThatTheVariantIsEnabled(ProductVariantInterface $productVariant): void { - Assert::true($this->indexPage->isSingleResourceOnPage([ - 'name' => $productVariant->getName(), - 'enabled' => 'Enabled', - ])); + Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage( + ['name' => $productVariant->getName()], + '[data-test-status-enabled]', + )); } /** diff --git a/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php b/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php index 4a8358e7b4..5a0fccb2b9 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php +++ b/src/Sylius/Behat/Context/Ui/Admin/Helper/ValidationTrait.php @@ -30,12 +30,24 @@ trait ValidationTrait /** * @Then I should be notified that :field is too long - * * @Then I should be notified that :field should be no longer than :maxLength characters + * @Then I should be notified that :field should be no longer than :maxLength characters */ public function iShouldBeNotifiedThatFieldValueIsTooLong(string $field, int $maxLength = 255): void { + try { + $validationMessage = $this + ->resolveCurrentPage() + ->getValidationMessage('field_' . StringInflector::nameToLowercaseCode($field)) + ; + } catch (\InvalidArgumentException) { + $validationMessage = $this + ->resolveCurrentPage() + ->getValidationMessage(StringInflector::nameToLowercaseCode($field)) + ; + } + Assert::contains( - $this->resolveCurrentPage()->getValidationMessage(StringInflector::nameToLowercaseCode($field)), + $validationMessage, sprintf('must not be longer than %d characters.', $maxLength), ); } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php b/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php index dee4223a7c..f127fe5e38 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ImpersonatingCustomersContext.php @@ -14,10 +14,12 @@ declare(strict_types=1); namespace Sylius\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; +use Sylius\Behat\NotificationType; use Sylius\Behat\Page\Admin\Administrator\ImpersonateUserPageInterface; use Sylius\Behat\Page\Admin\Customer\ShowPageInterface; use Sylius\Behat\Page\Admin\DashboardPageInterface; use Sylius\Behat\Page\Shop\HomePageInterface; +use Sylius\Behat\Service\NotificationCheckerInterface; use Sylius\Component\Customer\Model\CustomerInterface; use Webmozart\Assert\Assert; @@ -28,6 +30,7 @@ final class ImpersonatingCustomersContext implements Context private DashboardPageInterface $dashboardPage, private HomePageInterface $homePage, private ImpersonateUserPageInterface $impersonateUserPage, + private NotificationCheckerInterface $notificationChecker, ) { } @@ -123,6 +126,6 @@ final class ImpersonatingCustomersContext implements Context */ public function iShouldSeeThatImpersonatingWasSuccessful($email) { - Assert::contains($this->customerShowPage->getSuccessFlashMessage(), $email); + $this->notificationChecker->checkNotification($email, NotificationType::success()); } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php b/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php index 11afaeb11a..5dc4d5700c 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/LoginContext.php @@ -116,7 +116,7 @@ final class LoginContext implements Context { $this->logInAgain($username, $password); - Assert::true($this->loginPage->hasValidationErrorWith('Error Invalid credentials.')); + Assert::true($this->loginPage->hasValidationErrorWith('Invalid credentials.')); Assert::false($this->dashboardPage->isOpen()); } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php index 7bb0fbd076..b812e52862 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingAdministratorsContext.php @@ -75,10 +75,11 @@ final class ManagingAdministratorsContext implements Context /** * @When I specify its name as :username * @When I do not specify its name + * @When I change its name to :username */ public function iSpecifyItsNameAs($username = null): void { - $this->createPage->specifyUsername($username ?? ''); + $this->createPage->setUsername($username ?? ''); } /** @@ -87,35 +88,20 @@ final class ManagingAdministratorsContext implements Context public function iSpecifyItsFieldAsTooLongString(string $field): void { match ($field) { - 'first name' => $this->createPage->specifyFirstName($this->getTooLongString()), - 'last name' => $this->createPage->specifyLastName($this->getTooLongString()), - 'username' => $this->createPage->specifyUsername($this->getTooLongString()), + 'first name' => $this->createPage->setFirstName($this->getTooLongString()), + 'last name' => $this->createPage->setLastName($this->getTooLongString()), + 'username' => $this->createPage->setUsername($this->getTooLongString()), }; } - /** - * @When I change its name to :username - */ - public function iChangeItsNameTo($username) - { - $this->updatePage->changeUsername($username); - } - /** * @When I specify its email as :email * @When I do not specify its email + * @When I change its email to :email */ public function iSpecifyItsEmailAs($email = null) { - $this->createPage->specifyEmail($email ?? ''); - } - - /** - * @When I change its email to :email - */ - public function iChangeItsEmailTo($email) - { - $this->updatePage->changeEmail($email); + $this->createPage->setEmail($email ?? ''); } /** @@ -123,7 +109,7 @@ final class ManagingAdministratorsContext implements Context */ public function iSpecifyItsLocaleAs($localeCode) { - $this->createPage->specifyLocale($localeCode); + $this->createPage->setLocale($localeCode); } /** @@ -131,25 +117,18 @@ final class ManagingAdministratorsContext implements Context */ public function iSetMyLocaleTo($localeCode) { - $this->updatePage->changeLocale($localeCode); + $this->updatePage->setLocale($localeCode); $this->updatePage->saveChanges(); } /** * @When I specify its password as :password * @When I do not specify its password + * @When I change its password to :password */ public function iSpecifyItsPasswordAs($password = null) { - $this->createPage->specifyPassword($password ?? ''); - } - - /** - * @When I change its password to :password - */ - public function iChangeItsPasswordTo($password) - { - $this->updatePage->changePassword($password); + $this->createPage->setPassword($password ?? ''); } /** @@ -264,7 +243,7 @@ final class ManagingAdministratorsContext implements Context */ public function iShouldBeNotifiedThatEmailMustBeUnique() { - Assert::same($this->createPage->getValidationMessage('email'), 'This email is already used.'); + Assert::same($this->createPage->getValidationMessage('field_email'), 'This email is already used.'); } /** @@ -272,7 +251,7 @@ final class ManagingAdministratorsContext implements Context */ public function iShouldBeNotifiedThatNameMustBeUnique() { - Assert::same($this->createPage->getValidationMessage('name'), 'This username is already used.'); + Assert::same($this->createPage->getValidationMessage('field_username'), 'This username is already used.'); } /** @@ -280,7 +259,7 @@ final class ManagingAdministratorsContext implements Context */ public function iShouldBeNotifiedThatFirstNameIsRequired($elementName) { - Assert::same($this->createPage->getValidationMessage($elementName), sprintf('Please enter your %s.', $elementName)); + Assert::same($this->createPage->getValidationMessage(sprintf('%s_%s', 'field', $elementName)), sprintf('Please enter your %s.', $elementName)); } /** @@ -288,7 +267,7 @@ final class ManagingAdministratorsContext implements Context */ public function iShouldBeNotifiedThatEmailIsNotValid() { - Assert::same($this->createPage->getValidationMessage('email'), 'This email is invalid.'); + Assert::same($this->createPage->getValidationMessage('field_email'), 'This email is invalid.'); } /** @@ -297,9 +276,9 @@ final class ManagingAdministratorsContext implements Context public function iShouldBeNotifiedThatThisFieldIsTooLong(string $field): void { match ($field) { - 'first name' => Assert::same($this->createPage->getValidationMessage('first_name'), 'First name must not be longer than 255 characters.'), - 'last name' => Assert::same($this->createPage->getValidationMessage('last_name'), 'Last name must not be longer than 255 characters.'), - 'username' => Assert::same($this->createPage->getValidationMessage('name'), 'Username must not be longer than 255 characters.'), + 'first name' => Assert::same($this->createPage->getValidationMessage('field_first_name'), 'First name must not be longer than 255 characters.'), + 'last name' => Assert::same($this->createPage->getValidationMessage('field_last_name'), 'Last name must not be longer than 255 characters.'), + 'username' => Assert::same($this->createPage->getValidationMessage('field_username'), 'Username must not be longer than 255 characters.'), }; } @@ -360,8 +339,8 @@ final class ManagingAdministratorsContext implements Context { $avatarPath = $this->sharedStorage->get($avatar); - Assert::false($this->topBarElement->hasAvatarInMainBar($avatarPath)); - Assert::true($this->topBarElement->hasDefaultAvatarInMainBar()); + Assert::false($this->topBarElement->hasAvatarInMainBar($avatarPath), 'Avatar should not be present in the top bar'); + Assert::true($this->topBarElement->hasDefaultAvatarInMainBar(), 'Default avatar should be present in the top bar'); } /** diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php index b2372fe8a1..205115868f 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingCatalogPromotionsContext.php @@ -25,6 +25,11 @@ use Sylius\Behat\Page\Admin\CatalogPromotion\UpdatePageInterface; use Sylius\Behat\Page\Admin\Crud\IndexPageInterface; use Sylius\Behat\Service\NotificationCheckerInterface; use Sylius\Behat\Service\SharedStorageInterface; +use Sylius\Bundle\CoreBundle\CatalogPromotion\Calculator\FixedDiscountPriceCalculator; +use Sylius\Bundle\CoreBundle\CatalogPromotion\Calculator\PercentageDiscountPriceCalculator; +use Sylius\Bundle\CoreBundle\CatalogPromotion\Checker\InForProductScopeVariantChecker; +use Sylius\Bundle\CoreBundle\CatalogPromotion\Checker\InForTaxonsScopeVariantChecker; +use Sylius\Bundle\CoreBundle\CatalogPromotion\Checker\InForVariantsScopeVariantChecker; use Sylius\Component\Core\Formatter\StringInflector; use Sylius\Component\Core\Model\CatalogPromotionInterface; use Sylius\Component\Core\Model\ChannelInterface; @@ -38,14 +43,14 @@ final class ManagingCatalogPromotionsContext implements Context use ValidationTrait; public function __construct( - private IndexPageInterface $indexPage, - private CreatePageInterface $createPage, - private UpdatePageInterface $updatePage, - private ShowPageInterface $showPage, - private FormElementInterface $formElement, - private FilterElementInterface $filterElement, - private SharedStorageInterface $sharedStorage, - private NotificationCheckerInterface $notificationChecker, + private readonly IndexPageInterface $indexPage, + private readonly CreatePageInterface $createPage, + private readonly UpdatePageInterface $updatePage, + private readonly ShowPageInterface $showPage, + private readonly FormElementInterface $formElement, + private readonly FilterElementInterface $filterElement, + private readonly SharedStorageInterface $sharedStorage, + private readonly NotificationCheckerInterface $notificationChecker, ) { } @@ -208,7 +213,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddANewCatalogPromotionScope(): void { - $this->formElement->addScope(); + $this->formElement->addScope(InForProductScopeVariantChecker::TYPE); } /** @@ -220,9 +225,8 @@ final class ManagingCatalogPromotionsContext implements Context { $variantCodes = array_map(fn (ProductVariantInterface $variant) => $variant->getCode(), $variants); - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For variants'); - $this->formElement->chooseLastScopeCodes($variantCodes); + $this->formElement->addScope(InForVariantsScopeVariantChecker::TYPE); + $this->formElement->selectScopeOption($variantCodes); } /** @@ -232,9 +236,8 @@ final class ManagingCatalogPromotionsContext implements Context { $taxonsCodes = array_map(fn (TaxonInterface $taxon) => $taxon->getCode(), $taxons); - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For taxons'); - $this->formElement->chooseLastScopeCodes($taxonsCodes); + $this->formElement->addScope(InForTaxonsScopeVariantChecker::TYPE); + $this->formElement->selectScopeOption($taxonsCodes); } /** @@ -242,17 +245,32 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddScopeThatAppliesOnProduct(ProductInterface $product): void { - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For product'); - $this->formElement->chooseLastScopeCodes([$product->getCode()]); + $this->formElement->addScope(InForProductScopeVariantChecker::TYPE); + $this->formElement->selectScopeOption([$product->getCode()]); } /** - * @When I remove its every action + * @When I add :productVariant variant to its scope */ - public function iRemoveItsEveryAction(): void + public function iAddVariantToItsScope(ProductVariantInterface $productVariant): void { - $this->formElement->removeAllActions(); + $this->formElement->selectScopeOption([$productVariant->getCode()]); + } + + /** + * @When I remove :productVariant variant from its scope + */ + public function iRemoveVariantFromItsScope(ProductVariantInterface $productVariant): void + { + $this->formElement->removeScopeOption([$productVariant->getCode()]); + } + + /** + * @When I remove its last action + */ + public function iRemoveItsLastAction(): void + { + $this->formElement->removeLastAction(); } /** @@ -260,7 +278,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddANewCatalogPromotionAction(): void { - $this->formElement->addAction(); + $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE); } /** @@ -269,9 +287,8 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddActionThatGivesPercentageDiscount(string $discount): void { - $this->formElement->addAction(); - $this->formElement->chooseActionType('Percentage discount'); - $this->formElement->specifyLastActionDiscount($discount); + $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE); + $this->formElement->fillActionOption('Amount', $discount); } /** @@ -279,9 +296,8 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddActionThatGivesFixedDiscount(string $discount, ChannelInterface $channel): void { - $this->formElement->addAction(); - $this->formElement->chooseActionType('Fixed discount'); - $this->formElement->specifyLastActionDiscountForChannel($discount, $channel); + $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $discount); } /** @@ -347,87 +363,11 @@ final class ManagingCatalogPromotionsContext implements Context } /** - * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" variant)$/ + * @When I remove its last scope */ - public function iEditCatalogPromotionToBeAppliedOnVariant(CatalogPromotionInterface $catalogPromotion, ProductVariantInterface $productVariant): void + public function iRemoveItsLastScope(): void { - $this->updatePage->open(['id' => $catalogPromotion->getId()]); - - $this->formElement->chooseLastScopeCodes([$productVariant->getCode()]); - $this->updatePage->saveChanges(); - } - - /** - * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" taxon)$/ - */ - public function iEditCatalogPromotionToBeAppliedOnTaxon( - CatalogPromotionInterface $catalogPromotion, - TaxonInterface $taxon, - ): void { - $this->updatePage->open(['id' => $catalogPromotion->getId()]); - - $this->formElement->chooseScopeType('For taxons'); - $this->formElement->chooseLastScopeCodes([$taxon->getCode()]); - $this->updatePage->saveChanges(); - } - - /** - * @When /^I edit ("[^"]+" catalog promotion) to be applied on ("[^"]+" product)$/ - */ - public function iEditCatalogPromotionToBeAppliedOnProduct( - CatalogPromotionInterface $catalogPromotion, - ProductInterface $product, - ): void { - $this->updatePage->open(['id' => $catalogPromotion->getId()]); - - $this->formElement->chooseScopeType('For products'); - $this->formElement->chooseLastScopeCodes([$product->getCode()]); - $this->updatePage->saveChanges(); - } - - /** - * @When I remove its every scope - */ - public function iRemoveItsEveryScope(): void - { - $this->formElement->removeAllScopes(); - } - - /** - * @When /^I edit ("[^"]+" catalog promotion) to have "([^"]+)%" discount$/ - */ - public function iEditCatalogPromotionToHaveDiscount(CatalogPromotionInterface $catalogPromotion, string $amount): void - { - $this->updatePage->open(['id' => $catalogPromotion->getId()]); - $this->formElement->specifyLastActionDiscount($amount); - $this->updatePage->saveChanges(); - } - - /** - * @When /^I edit ("[^"]+" catalog promotion) to have "(?:€|£|\$)([^"]+)" of fixed discount in the ("[^"]+" channel)$/ - */ - public function iEditCatalogPromotionToHaveFixedDiscountInTheChannel( - CatalogPromotionInterface $catalogPromotion, - string $discount, - ChannelInterface $channel, - ): void { - $this->updatePage->open(['id' => $catalogPromotion->getId()]); - $this->formElement->chooseActionType('Fixed discount'); - $this->formElement->specifyLastActionDiscountForChannel($discount, $channel); - $this->updatePage->saveChanges(); - - $this->sharedStorage->set('catalog_promotion', $catalogPromotion); - } - - /** - * @When /^I edit it to have "(?:€|£|\$)([^"]+)" of fixed discount in the ("[^"]+" channel)$/ - */ - public function iEditItToHaveFixedDiscountInTheChannel( - string $discount, - ChannelInterface $channel, - ): void { - $this->formElement->chooseActionType('Fixed discount'); - $this->formElement->specifyLastActionDiscountForChannel($discount, $channel); + $this->formElement->removeLastScope(); } /** @@ -457,7 +397,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iEditItsActionSoThatItReducesPriceBy(string $discount): void { - $this->formElement->specifyLastActionDiscount($discount); + $this->formElement->fillActionOption('Amount', $discount); } /** @@ -465,8 +405,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddForVariantsScopeWithoutVariantsConfigured(): void { - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For variants'); + $this->formElement->addScope(InForVariantsScopeVariantChecker::TYPE); } /** @@ -474,8 +413,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddForTaxonScopeWithoutTaxonsConfigured(): void { - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For taxons'); + $this->formElement->addScope(InForTaxonsScopeVariantChecker::TYPE); } /** @@ -483,8 +421,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddCatalogPromotionScopeForProductWithoutProducts(): void { - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For products'); + $this->formElement->addScope(InForProductScopeVariantChecker::TYPE); } /** @@ -492,8 +429,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddPercentageDiscountActionWithoutAmountConfigured(): void { - $this->formElement->addAction(); - $this->formElement->chooseActionType('Percentage discount'); + $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE); } /** @@ -501,8 +437,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddFixedDiscountActionWithoutAmountConfigured(): void { - $this->formElement->addAction(); - $this->formElement->chooseActionType('Fixed discount'); + $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE); } /** @@ -510,8 +445,8 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iAddInvalidPercentageDiscountActionWithNonNumberInAmount(): void { - $this->formElement->addAction(); - $this->formElement->specifyLastActionDiscount('alot'); + $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE); + $this->formElement->fillActionOption('Amount', 'alot'); } /** @@ -520,9 +455,8 @@ final class ManagingCatalogPromotionsContext implements Context public function iAddInvalidFixedDiscountActionWithNonNumberInAmountForTheChannel( ChannelInterface $channel, ): void { - $this->formElement->addAction(); - $this->formElement->chooseActionType('Fixed discount'); - $this->formElement->specifyLastActionDiscountForChannel('wrong value', $channel); + $this->formElement->addAction(FixedDiscountPriceCalculator::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', 'wrong value'); } /** @@ -585,8 +519,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iEditItToHaveEmptyPercentageDiscount(): void { - $this->formElement->chooseActionType('Percentage discount'); - $this->formElement->specifyLastActionDiscount(''); + $this->formElement->fillActionOption('Amount', ''); } /** @@ -594,8 +527,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iEditItToHaveEmptyFixedDiscountInChannel(ChannelInterface $channel): void { - $this->formElement->chooseActionType('Fixed discount'); - $this->formElement->specifyLastActionDiscountForChannel('', $channel); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', ''); } /** @@ -705,7 +637,7 @@ final class ManagingCatalogPromotionsContext implements Context public function iShouldBeNotifiedThatADiscountAmountShouldBeBetween0And100Percent(): void { Assert::same( - $this->formElement->getValidationMessage(), + $this->formElement->getValidationMessage('last_action'), 'The percentage discount amount must be between 0% and 100%.', ); } @@ -716,19 +648,30 @@ final class ManagingCatalogPromotionsContext implements Context public function iShouldBeNotifiedThatThePercentageAmountShouldBeANumber(): void { Assert::same( - $this->formElement->getValidationMessage(), + $this->formElement->getValidationMessage('last_action'), 'The percentage discount amount must be a number and can not be empty.', ); } /** - * @Then I should be notified that the fixed amount should be a number and cannot be empty + * @Then I should be notified that the fixed amount cannot be empty + */ + public function iShouldBeNotifiedThatTheFixedAmountShouldCannotBeEmpty(): void + { + Assert::same( + $this->formElement->getValidationMessage('last_action'), + 'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.', + ); + } + + /** + * @Then I should be notified that the fixed amount should be a number */ public function iShouldBeNotifiedThatTheFixedAmountShouldBeANumber(): void { Assert::same( - $this->formElement->getValidationMessage(), - 'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.', + $this->formElement->getValidationMessage('last_action'), + 'Please enter a valid money amount.', ); } @@ -915,7 +858,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function itShouldHaveDiscount(string $amount): void { - Assert::same($this->formElement->getLastActionDiscount(), $amount); + Assert::same($this->formElement->getLastActionOption('Amount'), $amount); } /** @@ -929,7 +872,7 @@ final class ManagingCatalogPromotionsContext implements Context ): void { $this->updatePage->open(['id' => $catalogPromotion->getId()]); - Assert::same($this->formElement->getLastActionFixedDiscount($channel), $amount); + Assert::same($this->formElement->getLastActionOptionForChannel($channel->getCode(), 'Amount'), $amount); } /** @@ -1091,7 +1034,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iShouldBeNotifiedThatAtLeast1VariantIsRequired(): void { - Assert::same($this->formElement->getValidationMessage(), 'Please add at least 1 variant.'); + Assert::same($this->formElement->getValidationMessage('last_scope'), 'Please add at least 1 variant.'); } /** @@ -1100,7 +1043,7 @@ final class ManagingCatalogPromotionsContext implements Context public function iShouldBeNotifiedThatIMustAddAtLeastOne(string $entity): void { Assert::same( - $this->formElement->getValidationMessage(), + $this->formElement->getValidationMessage('last_scope'), sprintf('Provided configuration contains errors. Please add at least 1 %s.', $entity), ); } @@ -1110,9 +1053,9 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iShouldNotBeAbleToEditItDueToWrongState(): void { - Assert::same( - $this->formElement->getValidationMessage(), + Assert::inArray( 'The catalog promotion cannot be edited as it is currently being processed.', + $this->formElement->getValidationMessages(), ); } @@ -1186,7 +1129,7 @@ final class ManagingCatalogPromotionsContext implements Context */ public function iShouldGetInformationThatTheEndDateCannotBeSetBeforeStartDate(): void { - Assert::same($this->createPage->getValidationMessage('endDate'), 'End date cannot be set before start date.'); + Assert::same($this->formElement->getValidationMessage('end_date_date'), 'End date cannot be set before start date.'); } /** @@ -1195,7 +1138,7 @@ final class ManagingCatalogPromotionsContext implements Context public function iShouldBeNotifiedThatNotAllChannelsAreFilled(): void { Assert::contains( - $this->formElement->getValidationMessage(), + $this->formElement->getValidationMessage('last_action'), 'Provided configuration contains errors. Please add the fixed discount amount that is a number greater than 0.', ); } @@ -1214,7 +1157,7 @@ final class ManagingCatalogPromotionsContext implements Context public function iShouldSeeTheCatalogPromotionScopeConfigurationForm(): void { Assert::true( - $this->createPage->checkIfScopeConfigurationFormIsVisible(), + $this->formElement->checkIfScopeConfigurationFormIsVisible(), 'Catalog promotion scope configuration form is not visible.', ); } @@ -1225,7 +1168,7 @@ final class ManagingCatalogPromotionsContext implements Context public function iShouldSeeTheCatalogPromotionActionConfigurationForm(): void { Assert::true( - $this->createPage->checkIfActionConfigurationFormIsVisible(), + $this->formElement->checkIfActionConfigurationFormIsVisible(), 'Catalog promotion action configuration form is not visible.', ); } @@ -1264,12 +1207,10 @@ final class ManagingCatalogPromotionsContext implements Context $this->formElement->prioritizeIt($priority); $this->formElement->setExclusiveness($exclusive); $this->formElement->checkChannel($channel); - $this->formElement->addScope(); - $this->formElement->chooseScopeType('For product'); - $this->formElement->chooseLastScopeCodes([$product->getCode()]); - $this->formElement->addAction(); - $this->formElement->chooseActionType('Percentage discount'); - $this->formElement->specifyLastActionDiscount($discount); + $this->formElement->addScope(InForProductScopeVariantChecker::TYPE); + $this->formElement->selectScopeOption([$product->getCode()]); + $this->formElement->addAction(PercentageDiscountPriceCalculator::TYPE); + $this->formElement->fillActionOption('Amount', $discount); $this->createPage->create(); } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php index f0ee23587e..f0e91c1680 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingChannelsContext.php @@ -91,7 +91,9 @@ final class ManagingChannelsContext implements Context */ public function iChooseAsABaseCurrency(?CurrencyInterface $currency = null): void { - $this->createPage->chooseBaseCurrency($currency ? $currency->getName() : null); + if (null !== $currency) { + $this->createPage->chooseBaseCurrency($currency->getName()); + } } /** @@ -100,7 +102,9 @@ final class ManagingChannelsContext implements Context */ public function iChooseAsADefaultLocale(?string $defaultLocaleName = null): void { - $this->createPage->chooseDefaultLocale($defaultLocaleName); + if (null !== $defaultLocaleName) { + $this->createPage->chooseDefaultLocale($defaultLocaleName); + } } /** @@ -113,18 +117,11 @@ final class ManagingChannelsContext implements Context /** * @When I specify menu taxon as :menuTaxon + * @When I change its menu taxon to :menuTaxon */ public function iSpecifyMenuTaxonAs(string $menuTaxon): void { - $this->createPage->specifyMenuTaxon($menuTaxon); - } - - /** - * @When I change its menu taxon to :menuTaxon - */ - public function iChangeItsMenuTaxonTo(string $menuTaxon): void - { - $this->updatePage->changeMenuTaxon($menuTaxon); + $this->resolveCurrentPage()->specifyMenuTaxon($menuTaxon); } /** @@ -491,7 +488,7 @@ final class ManagingChannelsContext implements Context { $this->updatePage->open(['id' => $channel->getId()]); - Assert::true($this->updatePage->isLocaleChosen($nameOfLocale)); + Assert::inArray($nameOfLocale, $this->updatePage->getLocales()); } /** @@ -506,13 +503,13 @@ final class ManagingChannelsContext implements Context } /** - * @Then paying in :currencyCode should be possible for the :channel channel + * @Then paying in :currency should be possible for the :channel channel */ - public function payingInCurrencyShouldBePossibleForTheChannel(string $currencyCode, ChannelInterface $channel): void + public function payingInCurrencyShouldBePossibleForTheChannel(CurrencyInterface $currency, ChannelInterface $channel): void { $this->updatePage->open(['id' => $channel->getId()]); - Assert::true($this->updatePage->isCurrencyChosen($currencyCode)); + Assert::inArray($currency->getName(), $this->updatePage->getCurrencies()); } /** @@ -627,17 +624,17 @@ final class ManagingChannelsContext implements Context { $this->updatePage->open(['id' => $channel->getId()]); - Assert::true($this->updatePage->isDefaultTaxZoneChosen($taxZone)); + Assert::same($this->updatePage->getDefaultTaxZone(), $taxZone); } /** - * @Given channel :channel should not have default tax zone + * @Then channel :channel should not have default tax zone */ public function channelShouldNotHaveDefaultTaxZone(ChannelInterface $channel): void { $this->updatePage->open(['id' => $channel->getId()]); - Assert::false($this->updatePage->isAnyDefaultTaxZoneChosen()); + Assert::isEmpty($this->updatePage->getDefaultTaxZone()); } /** @@ -649,7 +646,10 @@ final class ManagingChannelsContext implements Context ): void { $this->updatePage->open(['id' => $channel->getId()]); - Assert::true($this->updatePage->isTaxCalculationStrategyChosen($taxCalculationStrategy)); + Assert::same( + $this->updatePage->getTaxCalculationStrategy(), + $taxCalculationStrategy, + ); } /** @@ -721,10 +721,10 @@ final class ManagingChannelsContext implements Context { $this->iWantToBrowseChannels(); - Assert::true($this->indexPage->isSingleResourceOnPage([ - 'nameAndDescription' => $channel->getName(), - 'enabled' => $state ? 'Enabled' : 'Disabled', - ])); + Assert::true($this->indexPage->isSingleResourceWithSpecificElementOnPage( + ['nameAndDescription' => $channel->getName()], + $state ? '[data-test-status-enabled]' : '[data-test-status-disabled]', + )); } private function getTooLongString(): string diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php index 734f8df69b..02702b732c 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingCountriesContext.php @@ -57,28 +57,33 @@ final class ManagingCountriesContext implements Context /** * @When I choose :countryName */ - public function iChoose($countryName) + public function iChoose(string $countryName): void { - $this->createPage->chooseName($countryName); + $this->createPage->selectCountry($countryName); } /** * @When I add the :provinceName province with :provinceCode code * @When I add the :provinceName province with :provinceCode code and :provinceAbbreviation abbreviation */ - public function iAddProvinceWithCode($provinceName, $provinceCode, $provinceAbbreviation = null) + public function iAddProvinceWithCode(string $provinceName, string $provinceCode, ?string $provinceAbbreviation = null): void { /** @var CreatePageInterface|UpdatePageInterface $currentPage */ $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - $currentPage->addProvince($provinceName, $provinceCode, $provinceAbbreviation); + $currentPage->addProvince(); + $currentPage->specifyProvinceName($provinceName); + $currentPage->specifyProvinceCode($provinceCode); + if (null !== $provinceAbbreviation) { + $currentPage->specifyProvinceAbbreviation($provinceAbbreviation); + } } /** * @When I add it * @When I try to add it */ - public function iAddIt() + public function iAddIt(): void { $this->createPage->create(); } @@ -94,7 +99,7 @@ final class ManagingCountriesContext implements Context /** * @When I disable it */ - public function iDisableIt() + public function iDisableIt(): void { $this->updatePage->disable(); } @@ -131,7 +136,7 @@ final class ManagingCountriesContext implements Context /** * @Then /^(this country) should be disabled$/ */ - public function thisCountryShouldBeDisabled(CountryInterface $country) + public function thisCountryShouldBeDisabled(CountryInterface $country): void { $this->indexPage->open(); @@ -141,10 +146,10 @@ final class ManagingCountriesContext implements Context /** * @Then I should not be able to choose :name */ - public function iShouldNotBeAbleToChoose($name) + public function iShouldNotBeAbleToChoose(string $name): void { try { - $this->createPage->chooseName($name); + $this->createPage->selectCountry($name); } catch (ElementNotFoundException) { return; } @@ -155,7 +160,7 @@ final class ManagingCountriesContext implements Context /** * @Then I should not be able to edit its code */ - public function theCodeFieldShouldBeDisabled() + public function theCodeFieldShouldBeDisabled(): void { Assert::true($this->updatePage->isCodeFieldDisabled()); } @@ -217,7 +222,7 @@ final class ManagingCountriesContext implements Context /** * @When /^I(?:| also) delete the "([^"]*)" province of this country$/ */ - public function iDeleteTheProvinceOfCountry($provinceName) + public function iDeleteTheProvinceOfCountry($provinceName): void { $this->updatePage->removeProvince($provinceName); } @@ -225,27 +230,27 @@ final class ManagingCountriesContext implements Context /** * @When /^I want to create a new province in (country "([^"]*)")$/ */ - public function iWantToCreateANewProvinceInCountry(CountryInterface $country) + public function iWantToCreateANewProvinceInCountry(CountryInterface $country): void { $this->updatePage->open(['id' => $country->getId()]); - $this->updatePage->clickAddProvinceButton(); + $this->updatePage->addProvince(); } /** * @When I name the province :provinceName * @When I do not name the province */ - public function iNameTheProvince($provinceName = null) + public function iNameTheProvince($provinceName = null): void { - $this->updatePage->nameProvince($provinceName ?? ''); + $this->updatePage->specifyProvinceName($provinceName ?? ''); } /** * @When I do not specify the province code * @When I specify the province code as :provinceCode */ - public function iSpecifyTheProvinceCode($provinceCode = null) + public function iSpecifyTheProvinceCode($provinceCode = null): void { $this->updatePage->specifyProvinceCode($provinceCode ?? ''); } @@ -315,6 +320,9 @@ final class ManagingCountriesContext implements Context */ public function iShouldBeNotifiedThatProvincesThatAreInUseCannotBeDeleted(): void { - $this->notificationChecker->checkNotification('Error Cannot delete, the province is in use.', NotificationType::failure()); + $this->notificationChecker->checkNotification( + 'Error Cannot delete, the Province is in use.', + NotificationType::failure(), + ); } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php index 709783c202..ee2f152d26 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingCustomersContext.php @@ -20,6 +20,8 @@ use Sylius\Behat\Page\Admin\Customer\IndexPageInterface as CustomerIndexPageInte use Sylius\Behat\Page\Admin\Customer\ShowPageInterface; use Sylius\Behat\Page\Admin\Customer\UpdatePageInterface; use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface; +use Sylius\Component\Core\Formatter\StringInflector; +use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\CustomerInterface; use Webmozart\Assert\Assert; @@ -90,6 +92,15 @@ final class ManagingCustomersContext implements Context $this->createPage->create(); } + /** + * @When I search for customer by :phrase + */ + public function iSearchForCustomersWith(string $phrase): void + { + $this->indexPage->setFilterSearch($phrase); + $this->indexPage->filter(); + } + /** * @When I filter by group :groupName * @When I filter by groups :firstGroup and :secondGroup @@ -97,7 +108,7 @@ final class ManagingCustomersContext implements Context public function iFilterByGroup(string ...$groupsNames): void { foreach ($groupsNames as $groupName) { - $this->indexPage->specifyFilterGroup($groupName); + $this->indexPage->setFilterGroup($groupName); } $this->indexPage->filter(); @@ -192,7 +203,23 @@ final class ManagingCustomersContext implements Context } /** - * @Then /^I should see (\d+) customers in the list$/ + * @When /^I sort customers by (ascending|descending) registration date$/ + */ + public function iSortCustomersByRegistrationDate(string $order): void + { + $this->sortBy($order, 'createdAt'); + } + + /** + * @When /^I sort customers by (ascending|descending) (email|first name|last name)$/ + */ + public function iSortCustomersByField(string $order, string $field): void + { + $this->sortBy($order, StringInflector::nameToCamelCase($field)); + } + + /** + * @Then /^I should see (\d+) customers (?:in|on) the list$/ * @Then /^I should see a single customer on the list$/ */ public function iShouldSeeCustomersInTheList($amountOfCustomers = 1) @@ -202,12 +229,26 @@ final class ManagingCustomersContext implements Context /** * @Then I should see the customer :email in the list + * @Then I should see the customer :email on the list */ public function iShouldSeeTheCustomerInTheList($email) { Assert::true($this->indexPage->isSingleResourceOnPage(['email' => $email])); } + /** + * @Then /^the (first|last) customer should be "([^"]+)"$/ + */ + public function theFirstLastCustomerShouldBe(string $placement, string $email): void + { + $index = 'first' === $placement ? 0 : $this->indexPage->countItems() - 1; + + Assert::same( + $this->indexPage->getColumnFields('email')[$index], + $email, + ); + } + /** * @Then /^I should be notified that ([^"]+) is required$/ */ @@ -435,14 +476,6 @@ final class ManagingCustomersContext implements Context Assert::same($this->showPage->getCustomerPhoneNumber(), $phoneNumber); } - /** - * @Then /^(?:their|his) default address should be "([^"]+)"$/ - */ - public function hisShippingAddressShouldBe(string $defaultAddress): void - { - Assert::same($this->showPage->getDefaultAddress(), str_replace(',', '', $defaultAddress)); - } - /** * @Then their default address should be :firstName :lastName, :street, :postcode :city, :country */ @@ -456,7 +489,7 @@ final class ManagingCustomersContext implements Context ): void { Assert::same( $this->showPage->getDefaultAddress(), - sprintf('%s %s %s %s %s %s', $firstName, $lastName, $street, $city, strtoupper($country), $postcode), + sprintf('%s %s, %s, %s %s, %s', $firstName, $lastName, $street, $postcode, $city, ucwords($country)), ); } @@ -465,7 +498,7 @@ final class ManagingCustomersContext implements Context */ public function iShouldSeeInformationAboutNoExistingAccountForThisCustomer() { - Assert::true($this->showPage->hasAccount()); + Assert::false($this->showPage->hasAccount()); } /** @@ -645,26 +678,31 @@ final class ManagingCustomersContext implements Context } /** - * @Then /^I should see that they have placed (\d+) orders? in the "([^"]+)" channel$/ + * @Then /^I should see that they have placed (\d+) orders? in the ("[^"]+" channel)$/ */ - public function iShouldSeeThatTheyHavePlacedOrdersInTheChannel($ordersCount, $channelName) + public function iShouldSeeThatTheyHavePlacedOrdersInTheChannel($ordersCount, ChannelInterface $channel) { - Assert::same($this->showPage->getOrdersCountInChannel($channelName), (int) $ordersCount); + Assert::same($this->showPage->getOrdersCountInChannel($channel->getCode()), (int) $ordersCount); } /** - * @Then /^I should see that the overall total value of all their orders in the "([^"]+)" channel is "([^"]+)"$/ + * @Then /^I should see that the overall total value of all their orders in the ("[^"]+" channel) is "([^"]+)"$/ */ - public function iShouldSeeThatTheOverallTotalValueOfAllTheirOrdersInTheChannelIs($channelName, $ordersValue) + public function iShouldSeeThatTheOverallTotalValueOfAllTheirOrdersInTheChannelIs(ChannelInterface $channel, $ordersValue) { - Assert::same($this->showPage->getOrdersTotalInChannel($channelName), $ordersValue); + Assert::same($this->showPage->getOrdersTotalInChannel($channel->getCode()), $ordersValue); } /** - * @Then /^I should see that the average total value of their order in the "([^"]+)" channel is "([^"]+)"$/ + * @Then /^I should see that the average total value of their order in the ("[^"]+" channel) is "([^"]+)"$/ */ - public function iShouldSeeThatTheAverageTotalValueOfTheirOrderInTheChannelIs($channelName, $ordersValue) + public function iShouldSeeThatTheAverageTotalValueOfTheirOrderInTheChannelIs(ChannelInterface $channel, $ordersValue) { - Assert::same($this->showPage->getOrdersTotalInChannel($channelName), $ordersValue); + Assert::same($this->showPage->getAverageTotalInChannel($channel->getCode()), $ordersValue); + } + + private function sortBy(string $order, string $field): void + { + $this->indexPage->sortBy($field, str_starts_with($order, 'de') ? 'desc' : 'asc'); } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php index a13e575d01..5c9583bfb5 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingOrdersContext.php @@ -15,7 +15,6 @@ namespace Sylius\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; use Sylius\Behat\NotificationType; -use Sylius\Behat\Page\Admin\Order\HistoryPageInterface; use Sylius\Behat\Page\Admin\Order\IndexPageInterface; use Sylius\Behat\Page\Admin\Order\ShowPageInterface; use Sylius\Behat\Page\Admin\Order\UpdatePageInterface; @@ -24,19 +23,19 @@ use Sylius\Behat\Service\NotificationCheckerInterface; use Sylius\Behat\Service\SharedSecurityServiceInterface; use Sylius\Behat\Service\SharedStorageInterface; use Sylius\Component\Addressing\Model\AddressInterface; +use Sylius\Component\Addressing\Model\ProvinceInterface; use Sylius\Component\Core\Model\AdminUserInterface; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; use Webmozart\Assert\Assert; -final class ManagingOrdersContext implements Context +final readonly class ManagingOrdersContext implements Context { public function __construct( private SharedStorageInterface $sharedStorage, private IndexPageInterface $indexPage, private ShowPageInterface $showPage, private UpdatePageInterface $updatePage, - private HistoryPageInterface $historyPage, private ErrorPageInterface $errorPage, private NotificationCheckerInterface $notificationChecker, private SharedSecurityServiceInterface $sharedSecurityService, @@ -47,24 +46,16 @@ final class ManagingOrdersContext implements Context * @Given I am browsing orders * @When I browse orders */ - public function iBrowseOrders() + public function iBrowseOrders(): void { $this->indexPage->open(); } - /** - * @When I browse order's :order history - */ - public function iBrowseOrderHistory(OrderInterface $order) - { - $this->historyPage->open(['id' => $order->getId()]); - } - /** * @Given /^I am viewing the summary of (this order)$/ * @When I view the summary of the order :order */ - public function iSeeTheOrder(OrderInterface $order) + public function iSeeTheOrder(OrderInterface $order): void { $this->showPage->open(['id' => $order->getId()]); } @@ -80,7 +71,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I mark (this order) as paid$/ */ - public function iMarkThisOrderAsAPaid(OrderInterface $order) + public function iMarkThisOrderAsAPaid(OrderInterface $order): void { $this->showPage->completeOrderLastPayment($order); } @@ -88,7 +79,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I mark (this order)'s payment as refunded$/ */ - public function iMarkThisOrderSPaymentAsRefunded(OrderInterface $order) + public function iMarkThisOrderSPaymentAsRefunded(OrderInterface $order): void { $this->showPage->refundOrderLastPayment($order); } @@ -96,7 +87,7 @@ final class ManagingOrdersContext implements Context /** * @When specify its tracking code as :trackingCode */ - public function specifyItsTrackingCodeAs($trackingCode) + public function specifyItsTrackingCodeAs(string $trackingCode): void { $this->showPage->specifyTrackingCode($trackingCode); $this->sharedStorage->set('tracking_code', $trackingCode); @@ -105,7 +96,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I ship (this order)$/ */ - public function iShipThisOrder(OrderInterface $order) + public function iShipThisOrder(OrderInterface $order): void { $this->showPage->shipOrder($order); } @@ -113,7 +104,7 @@ final class ManagingOrdersContext implements Context /** * @When I switch the way orders are sorted by :fieldName */ - public function iSwitchSortingBy($fieldName) + public function iSwitchSortingBy(string $fieldName): void { $this->indexPage->sortBy($fieldName); } @@ -121,7 +112,7 @@ final class ManagingOrdersContext implements Context /** * @When I specify filter date from as :dateTime */ - public function iSpecifyFilterDateFromAs($dateTime) + public function iSpecifyFilterDateFromAs(string $dateTime): void { $this->indexPage->specifyFilterDateFrom($dateTime); } @@ -129,7 +120,7 @@ final class ManagingOrdersContext implements Context /** * @When I specify filter date to as :dateTime */ - public function iSpecifyFilterDateToAs($dateTime) + public function iSpecifyFilterDateToAs(string $dateTime): void { $this->indexPage->specifyFilterDateTo($dateTime); } @@ -137,7 +128,7 @@ final class ManagingOrdersContext implements Context /** * @When I choose :channelName as a channel filter */ - public function iChooseChannelAsAChannelFilter($channelName) + public function iChooseChannelAsAChannelFilter(string $channelName): void { $this->indexPage->chooseChannelFilter($channelName); } @@ -145,7 +136,7 @@ final class ManagingOrdersContext implements Context /** * @When I choose :methodName as a shipping method filter */ - public function iChooseMethodAsAShippingMethodFilter($methodName) + public function iChooseMethodAsAShippingMethodFilter(string $methodName): void { $this->indexPage->chooseShippingMethodFilter($methodName); } @@ -153,7 +144,7 @@ final class ManagingOrdersContext implements Context /** * @When I choose :currencyName as the filter currency */ - public function iChooseCurrencyAsTheFilterCurrency($currencyName) + public function iChooseCurrencyAsTheFilterCurrency(string $currencyName): void { $this->indexPage->chooseCurrencyFilter($currencyName); } @@ -161,7 +152,7 @@ final class ManagingOrdersContext implements Context /** * @When I specify filter total being greater than :total */ - public function iSpecifyFilterTotalBeingGreaterThan($total) + public function iSpecifyFilterTotalBeingGreaterThan(string $total): void { $this->indexPage->specifyFilterTotalGreaterThan($total); } @@ -169,7 +160,7 @@ final class ManagingOrdersContext implements Context /** * @When I specify filter total being less than :total */ - public function iSpecifyFilterTotalBeingLessThan($total) + public function iSpecifyFilterTotalBeingLessThan(string $total): void { $this->indexPage->specifyFilterTotalLessThan($total); } @@ -177,7 +168,7 @@ final class ManagingOrdersContext implements Context /** * @When I filter */ - public function iFilter() + public function iFilter(): void { $this->indexPage->filter(); } @@ -224,10 +215,22 @@ final class ManagingOrdersContext implements Context $this->showPage->resendShipmentConfirmationEmail(); } + /** + * @When I change the :addressType country to :country + */ + public function iChangeTheCountryTo(string $addressType, string $country): void + { + match ($addressType) { + 'shipping' => $this->updatePage->changeShippingCountry($country), + 'billing' => $this->updatePage->changeBillingCountry($country), + default => throw new \InvalidArgumentException(sprintf('Address type "%s" is not supported.', $addressType)), + }; + } + /** * @Then I should see a single order from customer :customer */ - public function iShouldSeeASingleOrderFromCustomer(CustomerInterface $customer) + public function iShouldSeeASingleOrderFromCustomer(CustomerInterface $customer): void { Assert::true($this->indexPage->isSingleResourceOnPage(['customer' => $customer->getEmail()])); } @@ -254,7 +257,7 @@ final class ManagingOrdersContext implements Context /** * @Then it should have been placed by the customer :customerEmail */ - public function itShouldBePlacedByCustomer($customerEmail) + public function itShouldBePlacedByCustomer(string $customerEmail): void { Assert::true($this->showPage->hasCustomer($customerEmail)); } @@ -268,7 +271,7 @@ final class ManagingOrdersContext implements Context string $postcode, string $city, string $countryName, - ) { + ): void { $this->itShouldBeShippedTo(null, $customerName, $street, $postcode, $city, $countryName); } @@ -282,7 +285,7 @@ final class ManagingOrdersContext implements Context string $postcode, string $city, string $countryName, - ) { + ): void { if (null !== $order) { $this->iSeeTheOrder($order); } @@ -300,7 +303,7 @@ final class ManagingOrdersContext implements Context string $postcode, string $city, string $countryName, - ) { + ): void { Assert::true($this->showPage->hasBillingAddress($customerName, $street, $postcode, $city, $countryName)); } @@ -319,6 +322,21 @@ final class ManagingOrdersContext implements Context Assert::true($this->showPage->hasBillingAddress($customerName, $street, $postcode, $city, $countryName)); } + /** + * @Then I should be able to choose the :province province for the :addressType address + */ + public function iShouldBeAbleToChooseTheProvinceForTheAddressType(ProvinceInterface $province, string $addressType): void + { + Assert::inArray( + $province->getName(), + match ($addressType) { + 'billing' => $this->updatePage->getAvailableProvincesForBillingAddress(), + 'shipping' => $this->updatePage->getAvailableProvincesForShippingAddress(), + default => [], + }, + ); + } + /** * @Then it should have no shipping address set */ @@ -330,7 +348,7 @@ final class ManagingOrdersContext implements Context /** * @Then it should be shipped via the :shippingMethodName shipping method */ - public function itShouldBeShippedViaShippingMethod($shippingMethodName) + public function itShouldBeShippedViaShippingMethod(string $shippingMethodName): void { Assert::true($this->showPage->hasShipment($shippingMethodName)); } @@ -338,7 +356,7 @@ final class ManagingOrdersContext implements Context /** * @Then it should be paid with :paymentMethodName */ - public function itShouldBePaidWith($paymentMethodName) + public function itShouldBePaidWith(string $paymentMethodName): void { Assert::true($this->showPage->hasPayment($paymentMethodName)); } @@ -347,15 +365,15 @@ final class ManagingOrdersContext implements Context * @Then /^it should have (\d+) items$/ * @Then I should see :amount orders in the list */ - public function itShouldHaveAmountOfItems($amount = 1) + public function itShouldHaveAmountOfItems(int $amount = 1): void { - Assert::same($this->showPage->countItems(), (int) $amount); + Assert::same($this->showPage->countItems(), $amount); } /** * @Then the product named :productName should be in the items list */ - public function theProductShouldBeInTheItemsList($productName) + public function theProductShouldBeInTheItemsList(string $productName): void { Assert::true($this->showPage->isProductInTheList($productName)); } @@ -363,7 +381,7 @@ final class ManagingOrdersContext implements Context /** * @Then the order's items total should be :itemsTotal */ - public function theOrdersItemsTotalShouldBe($itemsTotal) + public function theOrdersItemsTotalShouldBe(string $itemsTotal): void { Assert::eq($this->showPage->getItemsTotal(), $itemsTotal); } @@ -371,7 +389,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^the order's total should(?:| still) be "([^"]+)"$/ */ - public function theOrdersTotalShouldBe($total) + public function theOrdersTotalShouldBe(string $total): void { Assert::eq($this->showPage->getTotal(), $total); } @@ -395,7 +413,7 @@ final class ManagingOrdersContext implements Context /** * @Then the order's shipping total should be :shippingTotal */ - public function theOrdersShippingTotalShouldBe($shippingTotal) + public function theOrdersShippingTotalShouldBe(string $shippingTotal): void { Assert::eq($this->showPage->getShippingTotal(), $shippingTotal); } @@ -403,7 +421,7 @@ final class ManagingOrdersContext implements Context /** * @Then the order's payment should (also) be :paymentAmount */ - public function theOrdersPaymentShouldBe($paymentAmount) + public function theOrdersPaymentShouldBe(string $paymentAmount): void { Assert::eq($this->showPage->getPaymentAmount(), $paymentAmount); } @@ -411,7 +429,7 @@ final class ManagingOrdersContext implements Context /** * @Then the order should have tax :tax */ - public function theOrderShouldHaveTax($tax) + public function theOrderShouldHaveTax(string $tax): void { Assert::true($this->showPage->hasTax($tax)); } @@ -419,7 +437,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^the order's tax total should(?:| still) be "([^"]+)"$/ */ - public function theOrdersTaxTotalShouldBe($taxTotal) + public function theOrdersTaxTotalShouldBe(string $taxTotal): void { Assert::eq($this->showPage->getTaxTotal(), $taxTotal); } @@ -435,7 +453,7 @@ final class ManagingOrdersContext implements Context /** * @Then the order's shipping promotion should be :promotion */ - public function theOrdersShippingPromotionDiscountShouldBe($promotionData) + public function theOrdersShippingPromotionDiscountShouldBe(string $promotionData): void { Assert::same($this->showPage->getShippingPromotionData(), $promotionData); } @@ -443,7 +461,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^the order's promotion total should(?:| still) be "([^"]+)"$/ */ - public function theOrdersPromotionTotalShouldBe($promotionTotal) + public function theOrdersPromotionTotalShouldBe(string $promotionTotal): void { Assert::same($this->showPage->getOrderPromotionTotal(), $promotionTotal); } @@ -451,7 +469,7 @@ final class ManagingOrdersContext implements Context /** * @When I check :itemName data */ - public function iCheckData($itemName) + public function iCheckData(string $itemName): void { $this->sharedStorage->set('item', $itemName); } @@ -459,7 +477,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) code should be "([^"]+)"$/ */ - public function itemCodeShouldBe($itemName, $code) + public function itemCodeShouldBe(string $itemName, string $code): void { Assert::same($this->showPage->getItemCode($itemName), $code); } @@ -467,7 +485,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) unit price should be ([^"]+)$/ */ - public function itemUnitPriceShouldBe($itemName, $unitPrice) + public function itemUnitPriceShouldBe(string $itemName, int $unitPrice): void { Assert::eq($this->showPage->getItemUnitPrice($itemName), $unitPrice); } @@ -475,7 +493,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) discounted unit price should be ([^"]+)$/ */ - public function itemDiscountedUnitPriceShouldBe($itemName, $discountedUnitPrice) + public function itemDiscountedUnitPriceShouldBe(string $itemName, int $discountedUnitPrice): void { Assert::eq($this->showPage->getItemDiscountedUnitPrice($itemName), $discountedUnitPrice); } @@ -483,7 +501,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) quantity should be ([^"]+)$/ */ - public function itemQuantityShouldBe($itemName, $quantity) + public function itemQuantityShouldBe(string $itemName, int $quantity): void { Assert::eq($this->showPage->getItemQuantity($itemName), $quantity); } @@ -491,7 +509,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) subtotal should be ([^"]+)$/ */ - public function itemSubtotalShouldBe($itemName, $subtotal) + public function itemSubtotalShouldBe(string $itemName, int $subtotal): void { Assert::eq($this->showPage->getItemSubtotal($itemName), $subtotal); } @@ -499,7 +517,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) discount should be ([^"]+)$/ */ - public function theItemShouldHaveDiscount($itemName, $discount) + public function theItemShouldHaveDiscount(string $itemName, int $discount): void { Assert::eq($this->showPage->getItemDiscount($itemName), $discount); } @@ -507,7 +525,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) tax should be ([^"]+)$/ */ - public function itemTaxShouldBe($itemName, $tax) + public function itemTaxShouldBe(string $itemName, int $tax): void { Assert::eq($this->showPage->getItemTax($itemName), $tax); } @@ -523,7 +541,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(its) total should be ([^"]+)$/ */ - public function itemTotalShouldBe($itemName, $total) + public function itemTotalShouldBe(string $itemName, int $total): void { Assert::eq($this->showPage->getItemTotal($itemName), $total); } @@ -531,7 +549,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should be notified that the order's payment has been successfully completed */ - public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyCompleted() + public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyCompleted(): void { $this->notificationChecker->checkNotification( 'Payment has been successfully updated.', @@ -542,7 +560,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should be notified that the order's payment could not be finalized due to insufficient stock */ - public function iShouldBeNotifiedThatTheOrderSPaymentCouldNotBeFinalizedDueToInsufficientStock() + public function iShouldBeNotifiedThatTheOrderSPaymentCouldNotBeFinalizedDueToInsufficientStock(): void { $this->notificationChecker->checkNotification( 'The payment cannot be completed due to insufficient stock of the', @@ -553,7 +571,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should be notified that the order's payment has been successfully refunded */ - public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyRefunded() + public function iShouldBeNotifiedThatTheOrderSPaymentHasBeenSuccessfullyRefunded(): void { $this->notificationChecker->checkNotification( 'Payment has been successfully refunded.', @@ -565,7 +583,7 @@ final class ManagingOrdersContext implements Context * @Then it should have payment state :paymentState * @Then it should have payment with state :paymentState */ - public function itShouldHavePaymentState($paymentState) + public function itShouldHavePaymentState(string $paymentState): void { Assert::true($this->showPage->hasPayment($paymentState)); } @@ -573,7 +591,7 @@ final class ManagingOrdersContext implements Context /** * @Then it should have order's payment state :orderPaymentState */ - public function itShouldHaveOrderPaymentState($orderPaymentState) + public function itShouldHaveOrderPaymentState(string $orderPaymentState): void { Assert::same($this->showPage->getPaymentState(), $orderPaymentState); } @@ -581,7 +599,7 @@ final class ManagingOrdersContext implements Context /** * @Then it should have order's shipping state :orderShippingState */ - public function itShouldHaveOrderShippingState($orderShippingState) + public function itShouldHaveOrderShippingState(string $orderShippingState): void { Assert::same($this->showPage->getShippingState(), $orderShippingState); } @@ -589,7 +607,7 @@ final class ManagingOrdersContext implements Context /** * @Then it's payment state should be refunded */ - public function orderPaymentStateShouldBeRefunded() + public function orderPaymentStateShouldBeRefunded(): void { Assert::same($this->showPage->getPaymentState(), 'Refunded'); } @@ -597,7 +615,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^I should not be able to mark (this order) as paid again$/ */ - public function iShouldNotBeAbleToFinalizeItsPayment(OrderInterface $order) + public function iShouldNotBeAbleToFinalizeItsPayment(OrderInterface $order): void { Assert::false($this->showPage->canCompleteOrderLastPayment($order)); } @@ -605,10 +623,10 @@ final class ManagingOrdersContext implements Context /** * @Then I should be notified that the order has been successfully shipped */ - public function iShouldBeNotifiedThatTheOrderHasBeenSuccessfullyShipped() + public function iShouldBeNotifiedThatTheOrderHasBeenSuccessfullyShipped(): void { $this->notificationChecker->checkNotification( - 'Shipment has been successfully updated.', + 'Shipment has been successfully shipped.', NotificationType::success(), ); } @@ -616,7 +634,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^I should not be able to ship (this order)$/ */ - public function iShouldNotBeAbleToShipThisOrder(OrderInterface $order) + public function iShouldNotBeAbleToShipThisOrder(OrderInterface $order): void { Assert::false($this->showPage->canShipOrder($order)); } @@ -624,7 +642,7 @@ final class ManagingOrdersContext implements Context /** * @When I cancel this order */ - public function iCancelThisOrder() + public function iCancelThisOrder(): void { $this->showPage->cancelOrder(); } @@ -632,7 +650,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should be notified that it has been successfully updated */ - public function iShouldBeNotifiedAboutItHasBeenSuccessfullyCanceled() + public function iShouldBeNotifiedAboutItHasBeenSuccessfullyCanceled(): void { $this->notificationChecker->checkNotification( 'Order has been successfully updated.', @@ -643,7 +661,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should not be able to cancel this order */ - public function iShouldNotBeAbleToCancelThisOrder() + public function iShouldNotBeAbleToCancelThisOrder(): void { Assert::false($this->showPage->hasCancelButton()); } @@ -652,7 +670,7 @@ final class ManagingOrdersContext implements Context * @Then this order should have state :state * @Then its state should be :state */ - public function itsStateShouldBe($state) + public function itsStateShouldBe(string $state): void { Assert::same($this->showPage->getOrderState(), $state); } @@ -660,7 +678,7 @@ final class ManagingOrdersContext implements Context /** * @Then it should( still) have a :state state */ - public function itShouldHaveState($state) + public function itShouldHaveState(string $state): void { Assert::true($this->indexPage->isSingleResourceOnPage(['state' => $state])); } @@ -670,9 +688,9 @@ final class ManagingOrdersContext implements Context */ public function theCustomerServiceShouldKnowAboutThisAdditionalNotes( AdminUserInterface $user, - $note, + string $note, OrderInterface $order, - ) { + ): void { $this->sharedSecurityService->performActionAsAdminUser( $user, function () use ($note, $order) { @@ -686,7 +704,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should see an order with :orderNumber number */ - public function iShouldSeeOrderWithNumber($orderNumber) + public function iShouldSeeOrderWithNumber(string $orderNumber): void { Assert::true($this->indexPage->isSingleResourceOnPage(['number' => $orderNumber])); } @@ -694,7 +712,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should not see an order with :orderNumber number */ - public function iShouldNotSeeOrderWithNumber($orderNumber) + public function iShouldNotSeeOrderWithNumber(string $orderNumber): void { Assert::false($this->indexPage->isSingleResourceOnPage(['number' => $orderNumber])); } @@ -702,7 +720,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should not see any orders with currency :currencyCode */ - public function iShouldNotSeeAnyOrderWithCurrency($currencyCode) + public function iShouldNotSeeAnyOrderWithCurrency(string $currencyCode): void { Assert::false($this->indexPage->isSingleResourceOnPage(['currencyCode' => $currencyCode])); } @@ -710,7 +728,7 @@ final class ManagingOrdersContext implements Context /** * @Then the first order should have number :number */ - public function theFirstOrderShouldHaveNumber($number) + public function theFirstOrderShouldHaveNumber(string $number): void { Assert::eq($this->indexPage->getColumnFields('number')[0], $number); } @@ -718,15 +736,15 @@ final class ManagingOrdersContext implements Context /** * @Then it should have shipment in state :shipmentState */ - public function itShouldHaveShipmentState($shipmentState) + public function itShouldHaveShipmentState(string $shipmentState): void { - Assert::true($this->showPage->hasShipment($shipmentState)); + Assert::true($this->showPage->hasShipmentWithState($shipmentState)); } /** * @Then order :orderNumber should have shipment state :shippingState */ - public function thisOrderShipmentStateShouldBe($shippingState) + public function thisOrderShipmentStateShouldBe(string $shippingState): void { Assert::true($this->indexPage->isSingleResourceOnPage(['shippingState' => $shippingState])); } @@ -735,7 +753,7 @@ final class ManagingOrdersContext implements Context * @Then the order :order should have order payment state :orderPaymentState * @Then /^(this order) should have order payment state "([^"]+)"$/ */ - public function theOrderShouldHavePaymentState(OrderInterface $order, $orderPaymentState) + public function theOrderShouldHavePaymentState(OrderInterface $order, string $orderPaymentState): void { Assert::true($this->indexPage->isSingleResourceOnPage(['paymentState' => $orderPaymentState])); } @@ -744,7 +762,7 @@ final class ManagingOrdersContext implements Context * @Then the order :order should have order shipping state :orderShippingState * @Then /^(this order) should have order shipping state "([^"]+)"$/ */ - public function theOrderShouldHaveShippingState(OrderInterface $order, $orderShippingState) + public function theOrderShouldHaveShippingState(OrderInterface $order, string $orderShippingState): void { Assert::true($this->indexPage->isSingleResourceOnPage(['shippingState' => $orderShippingState])); } @@ -752,7 +770,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^there should be(?:| only) (\d+) payments?$/ */ - public function theOrderShouldHaveNumberOfPayments($number) + public function theOrderShouldHaveNumberOfPayments(string $number): void { Assert::same($this->showPage->getPaymentsCount(), (int) $number); } @@ -760,7 +778,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should see the order :orderNumber with total :total */ - public function iShouldSeeTheOrderWithTotal($orderNumber, $total) + public function iShouldSeeTheOrderWithTotal(string $orderNumber, int $total): void { Assert::true($this->indexPage->isSingleResourceOnPage(['total' => $total])); } @@ -768,7 +786,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I want to modify a customer's (?:billing|shipping) address of (this order)$/ */ - public function iWantToModifyACustomerSShippingAddress(OrderInterface $order) + public function iWantToModifyACustomerSShippingAddress(OrderInterface $order): void { $this->updatePage->open(['id' => $order->getId()]); } @@ -777,7 +795,7 @@ final class ManagingOrdersContext implements Context * @When I save my changes * @When I try to save my changes */ - public function iSaveMyChanges() + public function iSaveMyChanges(): void { $this->updatePage->saveChanges(); } @@ -785,7 +803,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I specify their (?:|new )shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/ */ - public function iSpecifyTheirShippingAddressAsFor(AddressInterface $address) + public function iSpecifyTheirShippingAddressAsFor(AddressInterface $address): void { $this->updatePage->specifyShippingAddress($address); } @@ -793,7 +811,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I specify their (?:|new )billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/ */ - public function iSpecifyTheirBillingAddressAsFor(AddressInterface $address) + public function iSpecifyTheirBillingAddressAsFor(AddressInterface $address): void { $this->updatePage->specifyBillingAddress($address); } @@ -820,7 +838,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should see :provinceName as province in the shipping address */ - public function iShouldSeeAsProvinceInTheShippingAddress($provinceName) + public function iShouldSeeAsProvinceInTheShippingAddress(string $provinceName): void { Assert::true($this->showPage->hasShippingProvinceName($provinceName)); } @@ -828,7 +846,7 @@ final class ManagingOrdersContext implements Context /** * @Then I should see :provinceName as province in the billing address */ - public function iShouldSeeAdProvinceInTheBillingAddress($provinceName) + public function iShouldSeeAdProvinceInTheBillingAddress(string $provinceName): void { Assert::true($this->showPage->hasBillingProvinceName($provinceName)); } @@ -839,7 +857,7 @@ final class ManagingOrdersContext implements Context public function theAdministratorShouldKnowAboutIPAddressOfThisOrderMadeBy( AdminUserInterface $user, OrderInterface $order, - ) { + ): void { $this->sharedSecurityService->performActionAsAdminUser( $user, function () use ($order) { @@ -853,7 +871,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I (clear the billing address) information$/ */ - public function iClearTheBillingAddressInformation(AddressInterface $address) + public function iClearTheBillingAddressInformation(AddressInterface $address): void { $this->updatePage->specifyBillingAddress($address); } @@ -861,7 +879,7 @@ final class ManagingOrdersContext implements Context /** * @When /^I (clear the shipping address) information$/ */ - public function iClearTheShippingAddressInformation(AddressInterface $address) + public function iClearTheShippingAddressInformation(AddressInterface $address): void { $this->updatePage->specifyShippingAddress($address); } @@ -877,8 +895,11 @@ final class ManagingOrdersContext implements Context /** * @Then /^(the administrator) should see that (order placed by "[^"]+") has "([^"]+)" currency$/ */ - public function theAdministratorShouldSeeThatThisOrderHasBeenPlacedIn(AdminUserInterface $user, OrderInterface $order, $currency) - { + public function theAdministratorShouldSeeThatThisOrderHasBeenPlacedIn( + AdminUserInterface $user, + OrderInterface $order, + string $currency, + ): void { $this->sharedSecurityService->performActionAsAdminUser($user, function () use ($order, $currency) { $this->showPage->open(['id' => $order->getId()]); @@ -889,7 +910,7 @@ final class ManagingOrdersContext implements Context /** * @Then /^(the administrator) should see the order with total "([^"]+)" in order list$/ */ - public function theAdministratorShouldSeeTheOrderWithTotalInOrderList(AdminUserInterface $user, $total) + public function theAdministratorShouldSeeTheOrderWithTotalInOrderList(AdminUserInterface $user, int $total): void { $this->sharedSecurityService->performActionAsAdminUser($user, function () use ($total) { $this->indexPage->open(); @@ -898,26 +919,10 @@ final class ManagingOrdersContext implements Context }); } - /** - * @Then there should be :count shipping address changes in the registry - */ - public function thereShouldBeCountShippingAddressChangesInTheRegistry(int $count): void - { - Assert::same($this->historyPage->countShippingAddressChanges(), $count); - } - - /** - * @Then there should be :count billing address changes in the registry - */ - public function thereShouldBeCountBillingAddressChangesInTheRegistry(int $count): void - { - Assert::same($this->historyPage->countBillingAddressChanges(), $count); - } - /** * @Then I should not be able to refund this payment */ - public function iShouldNotBeAbleToRefundThisPayment() + public function iShouldNotBeAbleToRefundThisPayment(): void { Assert::false($this->showPage->hasRefundButton()); } @@ -1032,7 +1037,7 @@ final class ManagingOrdersContext implements Context * * @throws \InvalidArgumentException */ - private function assertElementValidationMessage($type, $element, $expectedMessage) + private function assertElementValidationMessage(string $type, string $element, string $expectedMessage): void { $element = sprintf('%s_%s', $type, str_replace(' ', '_', $element)); Assert::true($this->updatePage->checkValidationMessageFor($element, $expectedMessage)); diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php index 531d3e778f..d525ad5579 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php @@ -14,26 +14,29 @@ declare(strict_types=1); namespace Sylius\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; +use Behat\Mink\Exception\ElementNotFoundException; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface; use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait; use Sylius\Behat\Page\Admin\Crud\IndexPageInterface; use Sylius\Behat\Page\Admin\PaymentMethod\CreatePageInterface; use Sylius\Behat\Page\Admin\PaymentMethod\UpdatePageInterface; -use Sylius\Behat\Service\NotificationCheckerInterface; use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface; +use Sylius\Component\Core\Formatter\StringInflector; use Sylius\Component\Payment\Model\PaymentMethodInterface; use Webmozart\Assert\Assert; -final class ManagingPaymentMethodsContext implements Context +final readonly class ManagingPaymentMethodsContext implements Context { use ValidationTrait; + /** + * @param string[] $gatewayFactories + */ public function __construct( private CreatePageInterface $createPage, private IndexPageInterface $indexPage, private UpdatePageInterface $updatePage, private CurrentPageResolverInterface $currentPageResolver, - private NotificationCheckerInterface $notificationChecker, private array $gatewayFactories, ) { } @@ -59,10 +62,64 @@ final class ManagingPaymentMethodsContext implements Context $currentPage->nameIt($name ?? '', $language); } + /** + * @When I update its :field with :value + */ + public function iUpdateItsWith(string $field, string $value): void + { + match ($field) { + 'Publishable key' => $this->updatePage->setStripePublishableKey($value), + 'Secret key' => $this->updatePage->setStripeSecretKey($value), + 'Username' => $this->updatePage->setPaypalGatewayUsername($value), + 'Password' => $this->updatePage->setPaypalGatewayPassword($value), + 'Signature' => $this->updatePage->setPaypalGatewaySignature($value), + default => throw new \InvalidArgumentException(sprintf('There is no configuration for "%s" field.', $field)), + }; + } + + /** + * @When I configure it with( only) :element + */ + public function iConfigureItWith(string $element): void + { + match ($element) { + 'Publishable key' => $this->createPage->setStripePublishableKey('TEST'), + 'Secret key' => $this->createPage->setStripeSecretKey('TEST'), + default => throw new \InvalidArgumentException(sprintf('There is no configuration for "%s" element.', $element)), + }; + } + + /** + * @When /^I set its "Username" as "([^"]+)", "Password" as "([^"]+)" and "Signature" as "([^"]+)"$/ + */ + public function iSetItsUsernameAsPasswordAsAndSignatureAs(string $username, string $password, string $signature): void + { + $this->updatePage->setPaypalGatewayUsername($username); + $this->updatePage->setPaypalGatewayPassword($password); + $this->updatePage->setPaypalGatewaySignature($signature); + } + + /** + * @When /^I set its "Publishable key" as "([^"]+)" and "Secret key" as "([^"]+)"$/ + */ + public function iSetItsPublishableKeyAsAndSecretKeyAs(string $publishableKey, string $secretKey): void + { + $this->updatePage->setStripePublishableKey($publishableKey); + $this->updatePage->setStripeSecretKey($secretKey); + } + + /** + * @When I enable sandbox mode + */ + public function iEnableSandboxMode(): void + { + $this->updatePage->enableSandboxMode(); + } + /** * @When I do not name it */ - public function iDoNotNameIt() + public function iDoNotNameIt(): void { // Intentionally left blank to fulfill context expectation } @@ -70,7 +127,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I enable it */ - public function iEnableIt() + public function iEnableIt(): void { $this->updatePage->enable(); } @@ -78,7 +135,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I disable it */ - public function iDisableIt() + public function iDisableIt(): void { $this->updatePage->disable(); } @@ -87,7 +144,7 @@ final class ManagingPaymentMethodsContext implements Context * @When I save my changes * @When I try to save my changes */ - public function iSaveMyChanges() + public function iSaveMyChanges(): void { $this->updatePage->saveChanges(); } @@ -96,25 +153,36 @@ final class ManagingPaymentMethodsContext implements Context * @When I delete the :paymentMethod payment method * @When I try to delete the :paymentMethod payment method */ - public function iDeletePaymentMethod(PaymentMethodInterface $paymentMethod) + public function iDeletePaymentMethod(PaymentMethodInterface $paymentMethod): void { $this->indexPage->open(); $this->indexPage->deleteResourceOnPage(['code' => $paymentMethod->getCode(), 'name' => $paymentMethod->getName()]); } /** - * @Then this payment method :element should be :value + * @Then /^(?:this payment method|its gateway configuration) "([^"]+)" should be "([^"]+)"$/ */ - public function thisPaymentMethodElementShouldBe($element, $value) + public function itsGatewayConfigurationShouldBe(string $element, string $value): void { - Assert::true($this->updatePage->hasResourceValues([$element => $value])); + Assert::true( + $this->updatePage->hasResourceValues([StringInflector::nameToLowercaseCode($element) => $value]), + sprintf('Expected "%s" to be "%s", but it is not.', StringInflector::nameToLowercaseCode($element), $value), + ); + } + + /** + * @Then this payment method should be in sandbox mode + */ + public function thisPaymentMethodShouldBeInSandboxMode(): void + { + Assert::true($this->updatePage->isPaymentMethodInSandboxMode()); } /** * @When I want to create a new offline payment method * @When I want to create a new payment method with :factory gateway factory */ - public function iWantToCreateANewPaymentMethod($factory = 'Offline') + public function iWantToCreateANewPaymentMethod(string $factory = 'Offline'): void { $this->createPage->open(['factory' => array_search($factory, $this->gatewayFactories, true)]); } @@ -131,7 +199,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I describe it as :description in :language */ - public function iDescribeItAsIn($description, $language) + public function iDescribeItAsIn(string $description, string $language): void { $this->createPage->describeIt($description, $language); } @@ -139,7 +207,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When make it available in channel :channel */ - public function iMakeItAvailableInChannel($channel) + public function iMakeItAvailableInChannel(string $channel): void { $this->createPage->checkChannel($channel); } @@ -147,7 +215,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Given I set its instruction as :instructions in :language */ - public function iSetItsInstructionAsIn($instructions, $language) + public function iSetItsInstructionAsIn(string $instructions, string $language): void { $this->createPage->setInstructions($instructions, $language); } @@ -155,8 +223,10 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I add it * @When I try to add it + * + * @throws ElementNotFoundException */ - public function iAddIt() + public function iAddIt(): void { $this->createPage->create(); } @@ -200,7 +270,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Given /^(this payment method) should still be in the registry$/ */ - public function thisPaymentMethodShouldStillBeInTheRegistry(PaymentMethodInterface $paymentMethod) + public function thisPaymentMethodShouldStillBeInTheRegistry(PaymentMethodInterface $paymentMethod): void { $this->thePaymentMethodShouldAppearInTheRegistry($paymentMethod->getName()); } @@ -209,7 +279,7 @@ final class ManagingPaymentMethodsContext implements Context * @Given I am browsing payment methods * @When I browse payment methods */ - public function iBrowsePaymentMethods() + public function iBrowsePaymentMethods(): void { $this->indexPage->open(); } @@ -233,7 +303,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then the first payment method on the list should have :field :value */ - public function theFirstPaymentMethodOnTheListShouldHave($field, $value) + public function theFirstPaymentMethodOnTheListShouldHave(string $field, string $value): void { Assert::same($this->indexPage->getColumnFields($field)[0], $value); } @@ -241,7 +311,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then the last payment method on the list should have :field :value */ - public function theLastPaymentMethodOnTheListShouldHave($field, $value) + public function theLastPaymentMethodOnTheListShouldHave(string $field, string $value): void { $values = $this->indexPage->getColumnFields($field); @@ -254,7 +324,7 @@ final class ManagingPaymentMethodsContext implements Context * @When I switch the way payment methods are sorted to descending by :field * @Given the payment methods are already sorted by :field */ - public function iSortPaymentMethodsBy($field) + public function iSortPaymentMethodsBy(string $field): void { $this->indexPage->sortBy($field); } @@ -271,16 +341,20 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then I should be notified that :element is required * @Then I should be notified that I have to specify payment method :element + * + * @throws ElementNotFoundException */ - public function iShouldBeNotifiedThatIsRequired($element) + public function iShouldBeNotifiedThatIsRequired(string $element): void { $this->assertFieldValidationMessage($element, sprintf('Please enter payment method %s.', $element)); } /** * @Then I should be notified that I have to specify paypal :element + * + * @throws ElementNotFoundException */ - public function iShouldBeNotifiedThatIHaveToSpecifyPaypal($element) + public function iShouldBeNotifiedThatIHaveToSpecifyPaypal(string $element): void { Assert::same( $this->createPage->getValidationMessage('paypal_' . $element), @@ -290,19 +364,23 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then I should be notified that I have to specify stripe :element + * + * @throws ElementNotFoundException */ public function iShouldBeNotifiedThatIHaveToSpecifyStripe(string $element): void { Assert::same( - $this->createPage->getValidationMessage('stripe_' . str_replace(' ', '_', $element)), - sprintf('Please enter stripe %s.', $element), + $this->createPage->getValidationMessage('stripe_' . str_replace(' ', '_', strtolower($element))), + sprintf('Please enter stripe %s.', strtolower($element)), ); } /** * @Then I should be notified that gateway name should contain only letters and underscores + * + * @throws ElementNotFoundException */ - public function iShouldBeNotifiedThatGatewayNameShouldContainOnlyLettersAndUnderscores() + public function iShouldBeNotifiedThatGatewayNameShouldContainOnlyLettersAndUnderscores(): void { Assert::same( $this->createPage->getValidationMessage('gateway_name'), @@ -313,7 +391,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then the payment method with :element :value should not be added */ - public function thePaymentMethodWithElementValueShouldNotBeAdded($element, $value) + public function thePaymentMethodWithElementValueShouldNotBeAdded(string $element, string $value): void { $this->iBrowsePaymentMethods(); @@ -323,7 +401,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then /^(this payment method) should still be named "([^"]+)"$/ */ - public function thisShippingMethodNameShouldBe(PaymentMethodInterface $paymentMethod, $paymentMethodName) + public function thisShippingMethodNameShouldBe(PaymentMethodInterface $paymentMethod, string $paymentMethodName): void { $this->iBrowsePaymentMethods(); @@ -334,10 +412,9 @@ final class ManagingPaymentMethodsContext implements Context } /** - * @param string $element - * @param string $expectedMessage + * @throws ElementNotFoundException */ - private function assertFieldValidationMessage($element, $expectedMessage) + private function assertFieldValidationMessage(string $element, string $expectedMessage): void { /** @var CreatePageInterface|UpdatePageInterface $currentPage */ $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); @@ -349,7 +426,7 @@ final class ManagingPaymentMethodsContext implements Context * @Then the code field should be disabled * @Then I should not be able to edit its code */ - public function theCodeFieldShouldBeDisabled() + public function theCodeFieldShouldBeDisabled(): void { Assert::true($this->updatePage->isCodeDisabled()); } @@ -357,7 +434,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then the factory name field should be disabled */ - public function theFactoryNameFieldShouldBeDisabled() + public function theFactoryNameFieldShouldBeDisabled(): void { Assert::true($this->updatePage->isFactoryNameFieldDisabled()); } @@ -365,7 +442,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then this payment method should be enabled */ - public function thisPaymentMethodShouldBeEnabled() + public function thisPaymentMethodShouldBeEnabled(): void { Assert::true($this->updatePage->isPaymentMethodEnabled()); } @@ -373,7 +450,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then this payment method should be disabled */ - public function thisPaymentMethodShouldBeDisabled() + public function thisPaymentMethodShouldBeDisabled(): void { Assert::false($this->updatePage->isPaymentMethodEnabled()); } @@ -383,9 +460,9 @@ final class ManagingPaymentMethodsContext implements Context */ public function thePaymentMethodShouldHaveInstructionsIn( PaymentMethodInterface $paymentMethod, - $instructions, - $language, - ) { + string $instructions, + string $language, + ): void { $this->iWantToModifyAPaymentMethod($paymentMethod); Assert::same($this->updatePage->getPaymentMethodInstructions($language), $instructions); @@ -396,8 +473,8 @@ final class ManagingPaymentMethodsContext implements Context */ public function thePaymentMethodShouldBeAvailableInChannel( PaymentMethodInterface $paymentMethod, - $channelName, - ) { + string $channelName, + ): void { $this->iWantToModifyAPaymentMethod($paymentMethod); Assert::true($this->updatePage->isAvailableInChannel($channelName)); @@ -406,7 +483,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then /^(this payment method) should no longer exist in the registry$/ */ - public function thisPaymentMethodShouldNoLongerExistInTheRegistry(PaymentMethodInterface $paymentMethod) + public function thisPaymentMethodShouldNoLongerExistInTheRegistry(PaymentMethodInterface $paymentMethod): void { Assert::false($this->indexPage->isSingleResourceOnPage([ 'code' => $paymentMethod->getCode(), @@ -416,8 +493,10 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then I should be notified that payment method with this code already exists + * + * @throws ElementNotFoundException */ - public function iShouldBeNotifiedThatPaymentMethodWithThisCodeAlreadyExists() + public function iShouldBeNotifiedThatPaymentMethodWithThisCodeAlreadyExists(): void { Assert::same($this->createPage->getValidationMessage('code'), 'The payment method with given code already exists.'); } @@ -425,7 +504,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @Then there should still be only one payment method with :element :code */ - public function thereShouldStillBeOnlyOnePaymentMethodWith($element, $code) + public function thereShouldStillBeOnlyOnePaymentMethodWith(string $element, string $code): void { $this->iBrowsePaymentMethods(); @@ -435,7 +514,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I configure it with test paypal credentials */ - public function iConfigureItWithTestPaypalCredentials() + public function iConfigureItWithTestPaypalCredentials(): void { /** @var CreatePageInterface|UpdatePageInterface $currentPage */ $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); @@ -448,7 +527,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I configure it for username :username with :signature signature */ - public function iConfigureItForUsernameWithSignature($username, $signature) + public function iConfigureItForUsernameWithSignature(string $username, string $signature): void { /** @var CreatePageInterface|UpdatePageInterface $currentPage */ $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); @@ -460,7 +539,7 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I do not specify configuration password */ - public function iDoNotSpecifyConfigurationPassword() + public function iDoNotSpecifyConfigurationPassword(): void { // Intentionally left blank to fulfill context expectation } @@ -468,23 +547,12 @@ final class ManagingPaymentMethodsContext implements Context /** * @When I configure it with test stripe gateway data */ - public function iConfigureItWithTestStripeGatewayData() + public function iConfigureItWithTestStripeGatewayData(): void { $this->createPage->setStripeSecretKey('TEST'); $this->createPage->setStripePublishableKey('TEST'); } - /** - * @When I configure it with only :element - */ - public function iConfigureItWithOnly(string $element): void - { - match ($element) { - 'publishable key' => $this->createPage->setStripePublishableKey('TEST'), - 'secret key' => $this->createPage->setStripeSecretKey('TEST'), - }; - } - /** * @Then I should be redirected to the previous page of only enabled payment methods */ diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php index 4266942e52..5b3fe73038 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPaymentsContext.php @@ -155,4 +155,17 @@ final class ManagingPaymentsContext implements Context { Assert::true($this->indexPage->isPaymentWithOrderNumberInPosition($orderNumber, $position)); } + + /** + * @When /^I sort payments by date in (ascending|descending) order$/ + */ + public function iSortPaymentsByRegistrationDate(string $order): void + { + $this->sortBy($order, 'createdAt'); + } + + private function sortBy(string $order, string $field): void + { + $this->indexPage->sortBy($field, str_starts_with($order, 'de') ? 'desc' : 'asc'); + } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php index 392837973e..7ab8c43a49 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductAssociationTypesContext.php @@ -14,10 +14,12 @@ declare(strict_types=1); namespace Sylius\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; -use Sylius\Behat\Page\Admin\ProductAssociationType\CreatePageInterface; +use Sylius\Behat\Element\Admin\ProductAssociationType\FormElementInterface; +use Sylius\Behat\Page\Admin\Crud\CreatePageInterface; +use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface; use Sylius\Behat\Page\Admin\ProductAssociationType\IndexPageInterface; -use Sylius\Behat\Page\Admin\ProductAssociationType\UpdatePageInterface; -use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface; +use Sylius\Behat\Service\SharedStorageInterface; +use Sylius\Component\Locale\Model\LocaleInterface; use Sylius\Component\Product\Model\ProductAssociationTypeInterface; use Webmozart\Assert\Assert; @@ -27,7 +29,8 @@ final class ManagingProductAssociationTypesContext implements Context private CreatePageInterface $createPage, private IndexPageInterface $indexPage, private UpdatePageInterface $updatePage, - private CurrentPageResolverInterface $currentPageResolver, + private FormElementInterface $formElement, + private SharedStorageInterface $sharedStorage, ) { } @@ -61,7 +64,7 @@ final class ManagingProductAssociationTypesContext implements Context */ public function iNameItIn($name, $language) { - $this->createPage->nameItIn($name, $language); + $this->formElement->setName($name, $language); } /** @@ -76,18 +79,18 @@ final class ManagingProductAssociationTypesContext implements Context * @When I rename it to :name in :language * @When I remove its name from :language translation */ - public function iRenameItToInLanguage(string $language, ?string $name = null): void + public function iRenameItToInLanguage(string $language, string $name = ''): void { - $this->updatePage->nameItIn($name ?? '', $language); + $this->formElement->setName($name, $language); } /** * @When I specify its code as :code * @When I do not specify its code */ - public function iSpecifyItsCodeAs($code = null) + public function iSpecifyItsCodeAs(string $code = '') { - $this->createPage->specifyCode($code ?? ''); + $this->formElement->setCode($code); } /** @@ -199,7 +202,7 @@ final class ManagingProductAssociationTypesContext implements Context */ public function iShouldNotBeAbleToEditItsCode(): void { - Assert::true($this->updatePage->isCodeDisabled()); + Assert::true($this->formElement->isCodeDisabled()); } /** @@ -220,7 +223,7 @@ final class ManagingProductAssociationTypesContext implements Context public function iShouldBeNotifiedThatProductAssociationTypeWithThisCodeAlreadyExists() { Assert::same( - $this->createPage->getValidationMessage('code'), + $this->formElement->getValidationMessage('code'), 'The association type with given code already exists.', ); } @@ -240,7 +243,13 @@ final class ManagingProductAssociationTypesContext implements Context */ public function iShouldBeNotifiedThatIsRequired($element) { - $this->assertFieldValidationMessage($element, sprintf('Please enter association type %s.', $element)); + /** @var LocaleInterface $locale */ + $locale = $this->sharedStorage->get('locale'); + + Assert::same( + $this->formElement->getValidationMessage($element, ['%locale%' => $locale->getCode()]), + sprintf('Please enter association type %s.', $element), + ); } /** @@ -252,16 +261,4 @@ final class ManagingProductAssociationTypesContext implements Context Assert::false($this->indexPage->isSingleResourceOnPage([$element => $value])); } - - /** - * @param string $element - * @param string $expectedMessage - */ - private function assertFieldValidationMessage($element, $expectedMessage) - { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - Assert::same($currentPage->getValidationMessage($element), $expectedMessage); - } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php index 4adfbec4f1..ecb9f85494 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductVariantsContext.php @@ -220,15 +220,15 @@ final class ManagingProductVariantsContext implements Context /** * @When I set the position of :name to :position */ - public function iSetThePositionOfTo($name, int $position) + public function iSetThePositionOfTo(string $name, int $position): void { $this->indexPage->setPosition($name, $position); } /** - * @When I save my new configuration + * @When I save my new elements order */ - public function iSaveMyNewConfiguration() + public function iSaveMyNewElementsOrder(): void { $this->indexPage->savePositions(); } @@ -320,7 +320,7 @@ final class ManagingProductVariantsContext implements Context ChannelInterface $channel, ): void { $this->generatePage->specifyCode($nthVariant - 1, $code); - $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel); + $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel->getCode()); } /** @@ -336,7 +336,7 @@ final class ManagingProductVariantsContext implements Context */ public function iSpecifyThereAreVariantsWithCost(int $nthVariant, int $price, ChannelInterface $channel): void { - $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel); + $this->generatePage->specifyPrice($nthVariant - 1, $price, $channel->getCode()); } /** @@ -565,10 +565,10 @@ final class ManagingProductVariantsContext implements Context /** * @Then /^I should be notified that prices in all channels must be defined for the (\d)(?:st|nd|rd|th) variant$/ */ - public function iShouldBeNotifiedThatPricesInAllChannelsMustBeDefinedForTheVariant($position) + public function iShouldBeNotifiedThatPricesInAllChannelsMustBeDefinedForTheVariant($position): void { Assert::same( - $this->generatePage->getPricesValidationMessage($position - 1), + $this->generatePage->getValidationMessage('channel_pricings', $position - 1), 'You must define price for every enabled channel.', ); } @@ -751,6 +751,22 @@ final class ManagingProductVariantsContext implements Context Assert::true($this->updatePage->isSelectedOptionValueOnPage($optionName, $optionValue)); } + /** + * @Then /^I should not be able to remove (\d)(?:st|nd|rd|th) product variant$/ + */ + public function iShouldNotBeAbleToRemove(int $nthVariant): void + { + Assert::false($this->generatePage->isProductVariantRemovable($nthVariant - 1)); + } + + /** + * @Then /^I should be able to remove (\d)(?:st|nd|rd|th) product variant$/ + */ + public function iShouldBeAbleToRemove(int $nthVariant): void + { + Assert::true($this->generatePage->isProductVariantRemovable($nthVariant - 1)); + } + /** * @param string $element * @param string $message diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php index 7a0b612136..8f7099fbb5 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingProductsContext.php @@ -579,14 +579,23 @@ final class ManagingProductsContext implements Context $this->createConfigurableProductPage->selectOption($optionName); } + /** + * @When I add the :attributeName attribute + * @When I add the :attributeName attribute to it + */ + public function iAddTheAttribute(string $attributeName): void + { + $this->createSimpleProductPage->addAttribute($attributeName); + } + /** * @When I set its :attributeName attribute to :value in :localeCode * @When I do not set its :attributeName attribute in :localeCode - * @When I add the :attributeName attribute + * @When I set the :attributeName attribute value to :value in :localeCode */ public function iSetItsAttributeTo(string $attributeName, ?string $value = null, $localeCode = 'en_US'): void { - $this->createSimpleProductPage->addAttribute($attributeName, $value ?? '', $localeCode); + $this->createSimpleProductPage->updateAttribute($attributeName, $value ?? '', $localeCode); } /** @@ -594,7 +603,7 @@ final class ManagingProductsContext implements Context */ public function iSelectValueInLanguageForTheAttribute(string $value, string $language, string $attribute): void { - $this->createSimpleProductPage->selectAttributeValue($attribute, $value, $language); + $this->createSimpleProductPage->updateAttribute($attribute, $value, $language); } /** @@ -602,7 +611,7 @@ final class ManagingProductsContext implements Context */ public function iSelectValueForTheAttribute(string $value, string $attribute): void { - $this->createSimpleProductPage->selectAttributeValue($attribute, $value, ''); + $this->createSimpleProductPage->updateAttribute($attribute, $value, ''); } /** @@ -610,7 +619,7 @@ final class ManagingProductsContext implements Context */ public function iSetItsNonTranslatableAttributeTo(string $attributeName, string $value): void { - $this->createSimpleProductPage->addNonTranslatableAttribute($attributeName, $value); + $this->createSimpleProductPage->updateAttribute($attributeName, $value, ''); } /** @@ -661,7 +670,7 @@ final class ManagingProductsContext implements Context ): void { $this->updateSimpleProductPage->open(['id' => $product->getId()]); - Assert::same($this->updateSimpleProductPage->getAttributeSelectText($attributeName, $localeCode), $value); + Assert::same($this->updateSimpleProductPage->getAttributeValue($attributeName, $localeCode), $value); } /** @@ -671,7 +680,7 @@ final class ManagingProductsContext implements Context { $this->updateSimpleProductPage->open(['id' => $product->getId()]); - Assert::same($this->updateSimpleProductPage->getNonTranslatableAttributeValue($attributeName), $value); + Assert::same($this->updateSimpleProductPage->getAttributeValue($attributeName, ''), $value); } /** @@ -895,15 +904,15 @@ final class ManagingProductsContext implements Context } /** - * @When I remove an associated product :productName from :productAssociationType + * @When I remove an associated product :product from :productAssociationType */ public function iRemoveAnAssociatedProductFromProductAssociation( - $productName, + ProductInterface $product, ProductAssociationTypeInterface $productAssociationType, ) { $currentPage = $this->resolveCurrentPage(); - $currentPage->removeAssociatedProduct($productName, $productAssociationType); + $currentPage->removeAssociatedProduct($product, $productAssociationType); } /** @@ -937,7 +946,7 @@ final class ManagingProductsContext implements Context { $currentPage = $this->resolveCurrentPage(); - Assert::true($currentPage->isImageWithTypeDisplayed($type)); + Assert::true($currentPage->hasImageWithType($type)); } /** @@ -963,7 +972,7 @@ final class ManagingProductsContext implements Context { $currentPage = $this->resolveCurrentPage(); - Assert::false($currentPage->isImageWithTypeDisplayed($code)); + Assert::false($currentPage->hasImageWithType($code)); } /** @@ -1041,33 +1050,45 @@ final class ManagingProductsContext implements Context } /** - * @Then this product should( also) have an association :productAssociationType with product :productName - * @Then this product should( also) have an association :productAssociationType with products :firstProductName and :secondProductName + * @Then this product should( also) have an association :productAssociationType with product :product */ - public function theProductShouldHaveAnAssociationWithProducts( + public function theProductShouldHaveAnAssociationWithProduct( ProductAssociationTypeInterface $productAssociationType, - ...$productsNames, + ProductInterface $product, ) { - foreach ($productsNames as $productName) { - Assert::true( - $this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType), - sprintf( - 'This product should have an association %s with product %s.', - $productAssociationType->getName(), - $productName, - ), - ); + Assert::true( + $this->updateSimpleProductPage->hasAssociatedProduct($product, $productAssociationType), + sprintf( + 'This product should have an association %s with product %s.', + $productAssociationType->getName(), + $product->getName(), + ), + ); + } + + /** + * @Then /^this product should have an (association "[^"]+") with (products "[^"]+" and "[^"]+")$/ + * @Then /^this product should also have an (association "[^"]+") with (products "[^"]+" and "[^"]+")$/ + * + * @param array $products + */ + public function theProductsShouldHaveAnAssociationWithProducts( + ProductAssociationTypeInterface $productAssociationType, + array $products, + ): void { + foreach ($products as $product) { + $this->theProductShouldHaveAnAssociationWithProduct($productAssociationType, $product); } } /** - * @Then this product should not have an association :productAssociationType with product :productName + * @Then this product should not have an association :productAssociationType with product :product */ public function theProductShouldNotHaveAnAssociationWithProduct( ProductAssociationTypeInterface $productAssociationType, - $productName, - ) { - Assert::false($this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType)); + ProductInterface $product, + ): void { + Assert::false($this->updateSimpleProductPage->hasAssociatedProduct($product, $productAssociationType)); } /** @@ -1267,7 +1288,7 @@ final class ManagingProductsContext implements Context */ public function iShouldSeeInventoryOfThisProduct(): void { - Assert::true($this->updateSimpleProductPage->hasInventoryTab()); + Assert::true($this->updateSimpleProductPage->hasTab('inventory')); } /** @@ -1275,7 +1296,7 @@ final class ManagingProductsContext implements Context */ public function iShouldNotSeeInventoryOfThisProduct(): void { - Assert::false($this->updateConfigurableProductPage->hasInventoryTab()); + Assert::false($this->updateConfigurableProductPage->hasTab('inventory')); } /** diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php index 54b92f6736..496b4e8541 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingPromotionsContext.php @@ -27,6 +27,16 @@ use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface; use Sylius\Behat\Service\SharedStorageInterface; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\PromotionInterface; +use Sylius\Component\Core\Promotion\Action\FixedDiscountPromotionActionCommand; +use Sylius\Component\Core\Promotion\Action\PercentageDiscountPromotionActionCommand; +use Sylius\Component\Core\Promotion\Action\UnitFixedDiscountPromotionActionCommand; +use Sylius\Component\Core\Promotion\Action\UnitPercentageDiscountPromotionActionCommand; +use Sylius\Component\Core\Promotion\Checker\Rule\CartQuantityRuleChecker; +use Sylius\Component\Core\Promotion\Checker\Rule\ContainsProductRuleChecker; +use Sylius\Component\Core\Promotion\Checker\Rule\CustomerGroupRuleChecker; +use Sylius\Component\Core\Promotion\Checker\Rule\HasTaxonRuleChecker; +use Sylius\Component\Core\Promotion\Checker\Rule\ItemTotalRuleChecker; +use Sylius\Component\Core\Promotion\Checker\Rule\TotalOfItemsFromTaxonRuleChecker; use Webmozart\Assert\Assert; final class ManagingPromotionsContext implements Context @@ -58,7 +68,7 @@ final class ManagingPromotionsContext implements Context * @When I want to browse promotions * @When I browse promotions */ - public function iWantToBrowsePromotions() + public function iWantToBrowsePromotions(): void { $this->indexPage->open(); } @@ -88,7 +98,7 @@ final class ManagingPromotionsContext implements Context */ public function iRemoveItsPriority(?int $priority = null): void { - $this->formElement->prioritizeIt($priority); + $this->formElement->setPriority($priority); } /** @@ -118,7 +128,7 @@ final class ManagingPromotionsContext implements Context */ public function iSpecifyItsLabelInLocaleCode(string $label, string $localeCode): void { - $this->createPage->specifyLabel($label, $localeCode); + $this->formElement->setLabel($label, $localeCode); } /** @@ -126,7 +136,7 @@ final class ManagingPromotionsContext implements Context */ public function iSpecifyItsLabelWithAStringExceedingTheLimitInLocale(string $localeCode): void { - $this->createPage->specifyLabel(str_repeat('a', 256), $localeCode); + $this->formElement->setLabel(str_repeat('a', 256), $localeCode); } /** @@ -135,7 +145,7 @@ final class ManagingPromotionsContext implements Context public function thePromotionShouldHaveLabelInLocale(PromotionInterface $promotion, string $label, string $localeCode): void { $this->updatePage->open(['id' => $promotion->getId()]); - $this->createPage->hasLabel($label, $localeCode); + $this->formElement->hasLabel($label, $localeCode); } /** @@ -144,19 +154,19 @@ final class ManagingPromotionsContext implements Context */ public function iAddTheHasTaxonRuleConfiguredWith(string ...$taxons): void { - $this->createPage->addRule('Has at least one from taxons'); + $this->formElement->addRule(HasTaxonRuleChecker::TYPE); - $this->createPage->selectAutocompleteRuleOption('Taxons', $taxons, true); + $this->formElement->selectAutocompleteRuleOptions($taxons); } /** * @When /^I add the "Total price of items from taxon" rule configured with "([^"]+)" taxon and "(?:€|£|\$)([^"]+)" amount for ("[^"]+" channel)$/ */ - public function iAddTheRuleConfiguredWith($taxonName, $amount, ChannelInterface $channel) + public function iAddTheRuleConfiguredWith(string $taxonName, $amount, ChannelInterface $channel): void { - $this->createPage->addRule('Total price of items from taxon'); - $this->createPage->selectAutocompleteRuleOption('Taxon', $taxonName); - $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', $amount); + $this->formElement->addRule(TotalOfItemsFromTaxonRuleChecker::TYPE); + $this->formElement->selectAutocompleteRuleOptions([$taxonName], $channel->getCode()); + $this->formElement->fillRuleOptionForChannel($channel->getCode(), 'Amount', $amount); } /** @@ -168,18 +178,27 @@ final class ManagingPromotionsContext implements Context $secondAmount, ChannelInterface $secondChannel, ) { - $this->createPage->addRule('Item total'); - $this->createPage->fillRuleOptionForChannel($firstChannel->getCode(), 'Amount', $firstAmount); - $this->createPage->fillRuleOptionForChannel($secondChannel->getCode(), 'Amount', $secondAmount); + $this->formElement->addRule(ItemTotalRuleChecker::TYPE); + $this->formElement->fillRuleOptionForChannel($firstChannel->getCode(), 'Amount', $firstAmount); + $this->formElement->fillRuleOptionForChannel($secondChannel->getCode(), 'Amount', $secondAmount); } /** - * @When /^I add the "([^"]+)" action configured with amount of "(?:€|£|\$)([^"]+)" for ("[^"]+" channel)$/ + * @When /^I add the "Order fixed discount" action configured with amount of "(?:€|£|\$)([^"]+)" for ("[^"]+" channel)$/ */ - public function iAddTheActionConfiguredWithAmountForChannel($actionType, $amount, ChannelInterface $channel) + public function iAddTheOrderFixedDiscountActionConfiguredWithAmountForChannel($amount, ChannelInterface $channel): void { - $this->createPage->addAction($actionType); - $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount); + $this->formElement->addAction(FixedDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount); + } + + /** + * @When /^I add the "Item fixed discount" action configured with amount of "(?:€|£|\$)([^"]+)" for ("[^"]+" channel)$/ + */ + public function iAddTheItemFixedDiscountActionConfiguredWithAmountForChannel($amount, ChannelInterface $channel): void + { + $this->formElement->addAction(UnitFixedDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount); } /** @@ -187,7 +206,7 @@ final class ManagingPromotionsContext implements Context */ public function itIsConfiguredWithAmountForChannel($amount, ChannelInterface $channel) { - $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Amount', $amount); } /** @@ -195,7 +214,7 @@ final class ManagingPromotionsContext implements Context */ public function iAddAMinPriceFilterRangeForChannel(ChannelInterface $channel, $minimum) { - $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Min', $minimum); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Min', $minimum); } /** @@ -203,7 +222,7 @@ final class ManagingPromotionsContext implements Context */ public function iAddAMaxPriceFilterRangeForChannel(ChannelInterface $channel, $maximum) { - $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Max', $maximum); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Max', $maximum); } /** @@ -216,44 +235,73 @@ final class ManagingPromotionsContext implements Context } /** - * @When I specify that this action should be applied to items from :taxonName category + * @When I specify that this action should be applied to items from :taxonName category for :channel channel */ - public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName) + public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory(string $taxonName, ChannelInterface $channel): void { - $this->createPage->selectAutoCompleteFilterOption('Taxons', $taxonName); + $this->formElement->selectAutocompleteActionFilterOptions([$taxonName], $channel->getCode(), 'taxons'); } /** - * @When /^I add the "([^"]+)" action configured with a percentage value of "(?:|-)([^"]+)%" for ("[^"]+" channel)$/ + * @When /^I add the "Item percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%" for ("[^"]+" channel)$/ */ - public function iAddTheActionConfiguredWithAPercentageValueForChannel( - string $actionType, + public function iAddTheItemPercentageDiscountActionConfiguredWithAPercentageValueForChannel( string $percentage, ChannelInterface $channel, ): void { - $this->createPage->addAction($actionType); - $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage); + $this->formElement->addAction(UnitPercentageDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage); } /** - * @When I add the :actionType action configured without a percentage value for :channel channel + * @When /^I add the "Order percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%" for ("[^"]+" channel)$/ */ - public function iAddTheActionConfiguredWithoutAPercentageValueForChannel( - string $actionType, + public function iAddTheOrderPercentageDiscountActionConfiguredWithAPercentageValueForChannel( + string $percentage, ChannelInterface $channel, ): void { - $this->createPage->addAction($actionType); - $this->createPage->fillActionOptionForChannel($channel->getCode(), 'Percentage', ''); + $this->formElement->addAction(PercentageDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', $percentage); } /** - * @When /^I add the "([^"]+)" action configured with a percentage value of "(?:|-)([^"]+)%"$/ - * @When I add the :actionType action configured without a percentage value + * @When I add the "Order percentage discount" action configured without a percentage value for :channel channel */ - public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percentage = null) + public function iAddTheOrderPercentageDiscountActionConfiguredWithoutAPercentageValueForChannel( + ChannelInterface $channel, + ): void { + $this->formElement->addAction(PercentageDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', ''); + } + + /** + * @When I add the "Item percentage discount" action configured without a percentage value for :channel channel + */ + public function iAddTheItemPercentageDiscountActionConfiguredWithoutAPercentageValueForChannel( + ChannelInterface $channel, + ): void { + $this->formElement->addAction(UnitPercentageDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOptionForChannel($channel->getCode(), 'Percentage', ''); + } + + /** + * @When /^I add the "Order percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%"$/ + * @When I add the "Order percentage discount" action configured without a percentage value + */ + public function iAddTheOrderPercentageDiscountActionConfiguredWithAPercentageValue($percentage = null) { - $this->createPage->addAction($actionType); - $this->createPage->fillActionOption('Percentage', $percentage ?? ''); + $this->formElement->addAction(PercentageDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOption('Percentage', $percentage ?? ''); + } + + /** + * @When /^I add the "Item percentage discount" action configured with a percentage value of "(?:|-)([^"]+)%"$/ + * @When I add the "Item percentage discount" action configured without a percentage value + */ + public function iAddTheItemPercentageDiscountActionConfiguredWithAPercentageValue($percentage = null) + { + $this->formElement->addAction(UnitPercentageDiscountPromotionActionCommand::TYPE); + $this->formElement->fillActionOption('Percentage', $percentage ?? ''); } /** @@ -261,8 +309,8 @@ final class ManagingPromotionsContext implements Context */ public function iAddTheCustomerGroupRuleConfiguredForGroup($customerGroupName) { - $this->createPage->addRule('Customer group'); - $this->createPage->selectRuleOption('Customer group', $customerGroupName); + $this->formElement->addRule(CustomerGroupRuleChecker::TYPE); + $this->formElement->selectRuleOption('Customer group', $customerGroupName); } /** @@ -273,6 +321,22 @@ final class ManagingPromotionsContext implements Context $this->indexPage->checkResourceOnPage(['name' => $promotionName]); } + /** + * @When I remove its last rule + */ + public function iRemoveItsLastRule(): void + { + $this->formElement->removeLastRule(); + } + + /** + * @When I remove its last action + */ + public function iRemoveItsLastAction(): void + { + $this->formElement->removeLastAction(); + } + /** * @When I delete them */ @@ -354,7 +418,7 @@ final class ManagingPromotionsContext implements Context */ public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists() { - Assert::same($this->createPage->getValidationMessage('code'), 'The promotion with given code already exists.'); + Assert::same($this->formElement->getValidationMessage('code'), 'The promotion with given code already exists.'); } /** @@ -380,18 +444,15 @@ final class ManagingPromotionsContext implements Context /** * @When I set its usage limit to :usageLimit */ - public function iSetItsUsageLimitTo($usageLimit) + public function iSetItsUsageLimitTo(int $usageLimit): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - $currentPage->fillUsageLimit($usageLimit); + $this->formElement->setUsageLimit($usageLimit); } /** * @Then the :promotion promotion should be available to be used only :usageLimit times */ - public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit) + public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, int $usageLimit): void { $this->iWantToModifyAPromotion($promotion); @@ -403,10 +464,7 @@ final class ManagingPromotionsContext implements Context */ public function iSetItAsExclusive(): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - $currentPage->makeExclusive(); + $this->formElement->makeExclusive(); } /** @@ -414,16 +472,13 @@ final class ManagingPromotionsContext implements Context */ public function iSetItAsNotAppliesToDiscountedByCatalogPromotionItems(): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - $currentPage->makeNotAppliesToDiscountedItem(); + $this->formElement->makeNotAppliesToDiscountedItem(); } /** * @Then the :promotion promotion should be exclusive */ - public function thePromotionShouldBeExclusive(PromotionInterface $promotion) + public function thePromotionShouldBeExclusive(PromotionInterface $promotion): void { $this->assertIfFieldIsTrue($promotion, 'exclusive'); } @@ -439,18 +494,15 @@ final class ManagingPromotionsContext implements Context /** * @When I make it coupon based */ - public function iMakeItCouponBased() + public function iMakeItCouponBased(): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - $currentPage->checkCouponBased(); + $this->formElement->makeCouponBased(); } /** * @Then the :promotion promotion should be coupon based */ - public function thePromotionShouldBeCouponBased(PromotionInterface $promotion) + public function thePromotionShouldBeCouponBased(PromotionInterface $promotion): void { $this->assertIfFieldIsTrue($promotion, 'coupon_based'); } @@ -458,18 +510,15 @@ final class ManagingPromotionsContext implements Context /** * @When I make it applicable for the :channelName channel */ - public function iMakeItApplicableForTheChannel($channelName) + public function iMakeItApplicableForTheChannel(string $channelName): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - $currentPage->checkChannel($channelName); + $this->formElement->checkChannel($channelName); } /** * @Then the :promotion promotion should be applicable for the :channelName channel */ - public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, $channelName) + public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, string $channelName): void { $this->iWantToModifyAPromotion($promotion); @@ -549,13 +598,10 @@ final class ManagingPromotionsContext implements Context /** * @When I make it available from :startsDate to :endsDate */ - public function iMakeItAvailableFromTo(\DateTimeInterface $startsDate, \DateTimeInterface $endsDate) + public function iMakeItAvailableFromTo(\DateTimeInterface $startsDate, \DateTimeInterface $endsDate): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - $currentPage->setStartsAt($startsDate); - $currentPage->setEndsAt($endsDate); + $this->formElement->setStartsAt($startsDate); + $this->formElement->setEndsAt($endsDate); } /** @@ -566,7 +612,6 @@ final class ManagingPromotionsContext implements Context $this->iWantToModifyAPromotion($promotion); Assert::true($this->updatePage->hasStartsAt($startsDate)); - Assert::true($this->updatePage->hasEndsAt($endsDate)); } @@ -575,19 +620,16 @@ final class ManagingPromotionsContext implements Context */ public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStarts(): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - Assert::same($currentPage->getValidationMessage('ends_at'), 'End date cannot be set prior start date.'); + Assert::same($this->formElement->getValidationMessage('ends_at_date'), 'End date cannot be set prior start date.'); } /** * @Then I should be notified that this value should not be blank */ - public function iShouldBeNotifiedThatThisValueShouldNotBeBlank() + public function iShouldBeNotifiedThatThisValueShouldNotBeBlank(): void { Assert::same( - $this->createPage->getValidationMessageForAction(), + $this->formElement->getValidationMessageForAction(), 'This value should not be blank.', ); } @@ -600,7 +642,7 @@ final class ManagingPromotionsContext implements Context public function iShouldBeNotifiedThatPercentageDiscountShouldBeBetween(): void { Assert::same( - $this->createPage->getValidationMessageForAction(), + $this->formElement->getValidationMessageForAction(), 'The percentage discount must be between 0% and 100%.', ); } @@ -621,18 +663,18 @@ final class ManagingPromotionsContext implements Context /** * @When I add the "Contains product" rule configured with the :productName product */ - public function iAddTheRuleConfiguredWithTheProduct($productName) + public function iAddTheRuleConfiguredWithTheProduct(string $productName): void { - $this->createPage->addRule('Contains product'); - $this->createPage->selectAutocompleteRuleOption('Product code', $productName); + $this->formElement->addRule(ContainsProductRuleChecker::TYPE); + $this->formElement->selectAutocompleteRuleOptions([$productName]); } /** - * @When I specify that this action should be applied to the :productName product + * @When I specify that this action should be applied to the :productName product for :channel channel */ - public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName) + public function iSpecifyThatThisActionShouldBeAppliedToTheProduct(string $productName, ChannelInterface $channel): void { - $this->createPage->selectAutoCompleteFilterOption('Products', $productName); + $this->formElement->selectAutocompleteActionFilterOptions([$productName], $channel->getCode(), 'products'); } /** @@ -686,7 +728,7 @@ final class ManagingPromotionsContext implements Context { $this->iWantToModifyAPromotion($promotion); - Assert::same($this->updatePage->getPriority(), $priority); + Assert::same($this->formElement->getPriority(), $priority); } /** @@ -757,17 +799,17 @@ final class ManagingPromotionsContext implements Context /** * @When I add a new rule */ - public function iAddANewRule() + public function iAddANewRule(): void { - $this->createPage->addRule(null); + $this->formElement->addRule(CartQuantityRuleChecker::TYPE); } /** * @When I add a new action */ - public function iAddANewAction() + public function iAddANewAction(): void { - $this->createPage->addAction(null); + $this->formElement->addAction(FixedDiscountPromotionActionCommand::TYPE); } /** @@ -789,9 +831,17 @@ final class ManagingPromotionsContext implements Context /** * @Then I should see the rule configuration form */ - public function iShouldSeeTheRuleConfigurationForm() + public function iShouldSeeTheRuleConfigurationForm(): void { - Assert::true($this->createPage->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is not visible.'); + Assert::true($this->formElement->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is not visible.'); + } + + /** + * @Then I should not see the rule configuration form + */ + public function iShouldNotSeeTheRuleConfigurationForm(): void + { + Assert::false($this->formElement->checkIfRuleConfigurationFormIsVisible(), 'Cart promotion rule configuration form is visible.'); } /** @@ -813,9 +863,17 @@ final class ManagingPromotionsContext implements Context /** * @Then I should see the action configuration form */ - public function iShouldSeeTheActionConfigurationForm() + public function iShouldSeeTheActionConfigurationForm(): void { - Assert::true($this->createPage->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is not visible.'); + Assert::true($this->formElement->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is not visible.'); + } + + /** + * @Then I should not see the action configuration form + */ + public function iShouldNotSeeTheActionConfigurationForm(): void + { + Assert::false($this->formElement->checkIfActionConfigurationFormIsVisible(), 'Cart promotion action configuration form is visible.'); } /** @@ -850,11 +908,8 @@ final class ManagingPromotionsContext implements Context */ public function iShouldBeNotifiedThatPromotionLabelIsTooLong(string $localeCode): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - Assert::same( - $currentPage->getValidationMessageForTranslation('label', $localeCode), + $this->formElement->getValidationMessageForTranslation('label', $localeCode), 'This value is too long. It should have 255 characters or less.', ); } @@ -883,12 +938,17 @@ final class ManagingPromotionsContext implements Context Assert::false($this->indexPage->isArchivalFilterEnabled()); } + /** + * @Then the :promotion promotion should be successfully created + */ + public function thePromotionShouldBeSuccessfullyCreated(PromotionInterface $promotion): void + { + $this->updatePage->verify(['id' => $promotion->getId()]); + } + private function assertFieldValidationMessage(string $element, string $expectedMessage) { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - Assert::same($currentPage->getValidationMessage($element), $expectedMessage); + Assert::same($this->formElement->getValidationMessage($element), $expectedMessage); } /** diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php index f25dd303a4..6839c1cf72 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingCategoriesContext.php @@ -194,7 +194,7 @@ class ManagingShippingCategoriesContext implements Context */ public function iShouldNotBeAbleToEditItsCode(): void { - Assert::true($this->updatePage->isCodeDisabled()); + Assert::true($this->updatePage->isCodeDisabled(), 'Shipping category code should be disabled'); } /** diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php index 6efea9bb28..cdc39dc49d 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingShippingMethodsContext.php @@ -14,34 +14,36 @@ 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\ShippingMethod\FormElementInterface; use Sylius\Behat\Page\Admin\ShippingMethod\CreatePageInterface; use Sylius\Behat\Page\Admin\ShippingMethod\IndexPageInterface; use Sylius\Behat\Page\Admin\ShippingMethod\UpdatePageInterface; -use Sylius\Behat\Service\NotificationCheckerInterface; -use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface; +use Sylius\Behat\Service\SharedStorageInterface; +use Sylius\Component\Addressing\Model\ZoneInterface; use Sylius\Component\Channel\Model\ChannelInterface; +use Sylius\Component\Core\Formatter\StringInflector; use Sylius\Component\Core\Model\ShippingMethodInterface; +use Sylius\Component\Core\Shipping\Checker\Rule\OrderTotalGreaterThanOrEqualRuleChecker; +use Sylius\Component\Core\Shipping\Checker\Rule\OrderTotalLessThanOrEqualRuleChecker; +use Sylius\Component\Shipping\Checker\Rule\TotalWeightGreaterThanOrEqualRuleChecker; +use Sylius\Component\Shipping\Checker\Rule\TotalWeightLessThanOrEqualRuleChecker; use Webmozart\Assert\Assert; -final class ManagingShippingMethodsContext implements Context +final readonly class ManagingShippingMethodsContext implements Context { - use ValidationTrait; - public function __construct( private IndexPageInterface $indexPage, private CreatePageInterface $createPage, private UpdatePageInterface $updatePage, - private CurrentPageResolverInterface $currentPageResolver, - private NotificationCheckerInterface $notificationChecker, + private FormElementInterface $shippingMethodFormElement, + private SharedStorageInterface $sharedStorage, ) { } /** * @When I want to create a new shipping method */ - public function iWantToCreateANewShippingMethod() + public function iWantToCreateANewShippingMethod(): void { $this->createPage->open(); } @@ -52,56 +54,56 @@ final class ManagingShippingMethodsContext implements Context */ public function iSpecifyItsCodeAs(?string $code = null): void { - $this->createPage->specifyCode($code ?? ''); + $this->shippingMethodFormElement->setCode($code ?? ''); } /** * @When I specify its position as :position */ - public function iSpecifyItsPositionAs(?int $position = null) + public function iSpecifyItsPositionAs(int $position): void { - $this->createPage->specifyPosition($position); + $this->shippingMethodFormElement->setPosition($position); } /** * @When I name it :name in :language * @When I rename it to :name in :language */ - public function iNameItIn($name, $language) + public function iNameItIn(string $name, string $language): void { - $this->createPage->nameIt($name, $language); + $this->shippingMethodFormElement->setName($name, $language); } /** * @When I describe it as :description in :language */ - public function iDescribeItAsIn($description, $language) + public function iDescribeItAsIn(string $description, string $language): void { - $this->createPage->describeIt($description, $language); + $this->shippingMethodFormElement->setDescription($description, $language); } /** - * @When I define it for the zone named :zoneName + * @When I define it for the zone named :zone */ - public function iDefineItForTheZone(string $zoneName): void + public function iDefineItForTheZone(ZoneInterface $zone): void { - $this->createPage->chooseZone($zoneName); + $this->shippingMethodFormElement->setZoneCode($zone->getCode()); + } + + /** + * @When I make it available in channel :channel + */ + public function iMakeItAvailableInChannel(ChannelInterface $channel): void + { + $this->shippingMethodFormElement->checkChannel($channel->getCode()); } /** * @When I specify its amount as :amount for :channel channel */ - public function iSpecifyItsAmountForChannel($amount, ChannelInterface $channel) + public function iSpecifyItsAmountForChannel(int $amount, ChannelInterface $channel): void { - $this->createPage->specifyAmountForChannel($channel->getCode(), $amount); - } - - /** - * @When I make it available in channel :channelName - */ - public function iMakeItAvailableInChannel($channelName) - { - $this->createPage->checkChannel($channelName); + $this->shippingMethodFormElement->setCalculatorConfigurationAmountForChannel($channel->getCode(), $amount); } /** @@ -117,9 +119,9 @@ final class ManagingShippingMethodsContext implements Context * @When I choose :calculatorName calculator * @When I do not specify amount for :calculatorName calculator */ - public function iChooseCalculator($calculatorName) + public function iChooseCalculator(string $calculatorName): void { - $this->createPage->chooseCalculator($calculatorName); + $this->shippingMethodFormElement->chooseCalculator($calculatorName); } /** @@ -169,15 +171,22 @@ final class ManagingShippingMethodsContext implements Context } /** - * @Then the shipping method :shippingMethod should be available in channel :channelName + * @Then the shipping method :shippingMethod should be available in channel :channel */ public function theShippingMethodShouldBeAvailableInChannel( ShippingMethodInterface $shippingMethod, - $channelName, - ) { + ChannelInterface $channel, + ): void { $this->iWantToModifyAShippingMethod($shippingMethod); - Assert::true($this->updatePage->isAvailableInChannel($channelName)); + Assert::true( + $this->shippingMethodFormElement->hasCheckedChannel($channel->getCode()), + sprintf( + 'Shipping method %s should be available in channel %s, but it is not.', + $shippingMethod->getName(), + $channel->getCode(), + ), + ); } /** @@ -185,7 +194,7 @@ final class ManagingShippingMethodsContext implements Context */ public function iShouldBeNotifiedThatShippingMethodWithThisCodeAlreadyExists() { - Assert::same($this->createPage->getValidationMessage('code'), 'The shipping method with given code already exists.'); + Assert::same($this->shippingMethodFormElement->getValidationMessage('code'), 'The shipping method with given code already exists.'); } /** @@ -212,7 +221,7 @@ final class ManagingShippingMethodsContext implements Context */ public function theCodeFieldShouldBeDisabled() { - Assert::true($this->updatePage->isCodeDisabled()); + Assert::true($this->shippingMethodFormElement->isCodeDisabled()); } /** @@ -239,11 +248,25 @@ final class ManagingShippingMethodsContext implements Context } /** - * @Then I should be notified that :element is required + * @Then /^I should be notified that (code) is required$/ */ - public function iShouldBeNotifiedThatIsRequired($element) + public function iShouldBeNotifiedThatCodeIsRequired(string $field): void { - $this->assertFieldValidationMessage($element, sprintf('Please enter shipping method %s.', $element)); + Assert::same( + $this->shippingMethodFormElement->getValidationMessage($field), + sprintf('Please enter shipping method %s.', $field), + ); + } + + /** + * @Then I should be notified that name is required + */ + public function iShouldBeNotifiedThatNameIsRequired($localeCode = 'en_US'): void + { + Assert::same( + $this->shippingMethodFormElement->getValidationMessage('name', ['%localeCode%' => $localeCode]), + 'Please enter shipping method name.', + ); } /** @@ -260,19 +283,17 @@ final class ManagingShippingMethodsContext implements Context /** * @When I archive the :name shipping method */ - public function iArchiveTheShippingMethod($name) + public function iArchiveTheShippingMethod(string $name): void { - $actions = $this->indexPage->getActionsForResource(['name' => $name]); - $actions->pressButton('Archive'); + $this->indexPage->archiveShippingMethod($name); } /** * @When I restore the :name shipping method */ - public function iRestoreTheShippingMethod($name) + public function iRestoreTheShippingMethod(string $name): void { - $actions = $this->indexPage->getActionsForResource(['name' => $name]); - $actions->pressButton('Restore'); + $this->indexPage->restoreShippingMethod($name); } /** @@ -331,9 +352,9 @@ final class ManagingShippingMethodsContext implements Context /** * @When I remove its zone */ - public function iRemoveItsZone() + public function iRemoveItsZone(): void { - $this->updatePage->removeZone(); + $this->shippingMethodFormElement->setZoneCode(''); } /** @@ -348,9 +369,9 @@ final class ManagingShippingMethodsContext implements Context /** * @When I remove its name from :language translation */ - public function iRemoveItsNameFromTranslation($language) + public function iRemoveItsNameFromTranslation(string $language): void { - $this->createPage->nameIt('', $language); + $this->shippingMethodFormElement->setName('', $language); } /** @@ -417,7 +438,7 @@ final class ManagingShippingMethodsContext implements Context */ public function iEnableIt() { - $this->updatePage->enable(); + $this->shippingMethodFormElement->enable(); } /** @@ -425,7 +446,15 @@ final class ManagingShippingMethodsContext implements Context */ public function iDisableIt() { - $this->updatePage->disable(); + $this->shippingMethodFormElement->disable(); + } + + /** + * @When I specify a too long :field + */ + public function iSpecifyATooLong(string $field): void + { + $this->shippingMethodFormElement->setField(ucwords($field), str_repeat('a', 256)); } /** @@ -433,7 +462,7 @@ final class ManagingShippingMethodsContext implements Context */ public function thisShippingMethodShouldBeDisabled(ShippingMethodInterface $shippingMethod) { - $this->assertShippingMethodState($shippingMethod, false); + Assert::true($this->indexPage->isShippingMethodDisabled($shippingMethod)); } /** @@ -441,7 +470,7 @@ final class ManagingShippingMethodsContext implements Context */ public function thisShippingMethodShouldBeEnabled(ShippingMethodInterface $shippingMethod) { - $this->assertShippingMethodState($shippingMethod, true); + Assert::true($this->indexPage->isShippingMethodEnabled($shippingMethod)); } /** @@ -450,8 +479,7 @@ final class ManagingShippingMethodsContext implements Context */ public function iDeleteShippingMethod(ShippingMethodInterface $shippingMethod) { - $this->indexPage->open(); - $this->indexPage->deleteResourceOnPage(['name' => $shippingMethod->getName()]); + $this->indexPage->deleteShippingMethod($shippingMethod->getName()); } /** @@ -467,11 +495,8 @@ final class ManagingShippingMethodsContext implements Context */ public function iShouldBeNotifiedThatAmountForChannelShouldNotBeBlank(ChannelInterface $channel) { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - Assert::same( - $currentPage->getValidationMessageForAmount($channel->getCode()), + $this->shippingMethodFormElement->getValidationMessage('calculator_configuration_amount', ['%channelCode%' => $channel->getCode()]), 'This value should not be blank.', ); } @@ -481,11 +506,8 @@ final class ManagingShippingMethodsContext implements Context */ public function iShouldBeNotifiedThatShippingChargeForChannelCannotBeLowerThan0(ChannelInterface $channel): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - Assert::same( - $currentPage->getValidationMessageForAmount($channel->getCode()), + $this->shippingMethodFormElement->getValidationMessage('calculator_configuration_amount', ['%channelCode%' => $channel->getCode()]), 'Shipping charge cannot be lower than 0.', ); } @@ -495,8 +517,8 @@ final class ManagingShippingMethodsContext implements Context */ public function iAddTheTotalWeightGreaterThanOrEqualRuleConfiguredWith(int $weight): void { - $this->createPage->addRule('Total weight greater than or equal'); - $this->createPage->fillRuleOption('Weight', (string) $weight); + $this->shippingMethodFormElement->addRule(TotalWeightGreaterThanOrEqualRuleChecker::TYPE); + $this->shippingMethodFormElement->fillLastRuleOption('Weight', (string) $weight); } /** @@ -504,8 +526,8 @@ final class ManagingShippingMethodsContext implements Context */ public function iAddTheTotalWeightGreaterThanOrEqualRuleConfiguredWithInvalidData(): void { - $this->createPage->addRule('Total weight greater than or equal'); - $this->createPage->fillRuleOption('Weight', 'invalid data'); + $this->shippingMethodFormElement->addRule(TotalWeightGreaterThanOrEqualRuleChecker::TYPE); + $this->shippingMethodFormElement->fillLastRuleOption('Weight', 'invalid data'); } /** @@ -513,8 +535,8 @@ final class ManagingShippingMethodsContext implements Context */ public function iAddTheTotalWeightLessThanOrEqualRuleConfiguredWith(int $weight): void { - $this->createPage->addRule('Total weight less than or equal'); - $this->createPage->fillRuleOption('Weight', (string) $weight); + $this->shippingMethodFormElement->addRule(TotalWeightLessThanOrEqualRuleChecker::TYPE); + $this->shippingMethodFormElement->fillLastRuleOption('Weight', (string) $weight); } /** @@ -522,8 +544,13 @@ final class ManagingShippingMethodsContext implements Context */ public function iAddTheItemsTotalLessThanOrEqualRuleConfiguredWith(string $rule, mixed $value, ChannelInterface $channel): void { - $this->createPage->addRule($rule); - $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', (string) $value); + $ruleTypes = [ + 'Items total less than or equal' => OrderTotalLessThanOrEqualRuleChecker::TYPE, + 'Items total greater than or equal' => OrderTotalGreaterThanOrEqualRuleChecker::TYPE, + ]; + + $this->shippingMethodFormElement->addRule($ruleTypes[$rule]); + $this->shippingMethodFormElement->fillLastRuleOptionForChannel($channel->getCode(), 'Amount', (string) $value); } /** @@ -531,8 +558,8 @@ final class ManagingShippingMethodsContext implements Context */ public function iAddTheItemsTotalLessThanOrEqualRuleConfiguredWithInvalidData(ChannelInterface $channel): void { - $this->createPage->addRule('Items total less than or equal'); - $this->createPage->fillRuleOptionForChannel($channel->getCode(), 'Amount', 'Invalid data'); + $this->shippingMethodFormElement->addRule(OrderTotalLessThanOrEqualRuleChecker::TYPE); + $this->shippingMethodFormElement->fillLastRuleOptionForChannel($channel->getCode(), 'Amount', 'Invalid data'); } /** @@ -540,7 +567,7 @@ final class ManagingShippingMethodsContext implements Context */ public function iRemoveTheShippingChargesOfChannel(ChannelInterface $channel): void { - $this->updatePage->removeShippingChargesAmount($channel->getCode()); + $this->shippingMethodFormElement->setCalculatorConfigurationAmountForChannel($channel->getCode(), null); } /** @@ -551,7 +578,7 @@ final class ManagingShippingMethodsContext implements Context int $count, ): void { Assert::same( - $this->updatePage->getShippingChargesValidationErrorsCount($channel->getCode()), + $this->shippingMethodFormElement->getShippingChargesValidationErrorsCount($channel->getCode()), $count, ); } @@ -561,7 +588,11 @@ final class ManagingShippingMethodsContext implements Context */ public function iShouldBeNotifiedThatTheWeightRuleHasAnInvalidConfiguration(): void { - $this->assertFieldValidationMessage('weight', 'Please enter a number.'); + $channel = $this->sharedStorage->get('channel'); + Assert::same( + $this->shippingMethodFormElement->getValidationMessage('last_rule_weight'), + 'Please enter a number.', + ); } /** @@ -569,42 +600,37 @@ final class ManagingShippingMethodsContext implements Context */ public function iShouldBeNotifiedThatTheAmountRuleHasAnInvalidConfigurationInChannel(ChannelInterface $channel): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - Assert::same( - $currentPage->getValidationMessageForRuleAmount($channel->getCode()), + $this->shippingMethodFormElement->getValidationMessage('last_rule_amount', ['%channelCode%' => $channel->getCode()]), 'Please enter a valid money amount.', ); } /** - * @param string $element - * @param string $expectedMessage + * @Then I should be notified that :field is too long + * @Then I should be notified that :field should be no longer than :maxLength characters */ - private function assertFieldValidationMessage($element, $expectedMessage) + public function iShouldBeNotifiedThatFieldValueIsTooLong(string $field, int $maxLength = 255): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); + $validationMessage = $this->shippingMethodFormElement->getValidationMessage(StringInflector::nameToLowercaseCode($field)); - Assert::same($currentPage->getValidationMessage($element), $expectedMessage); + Assert::contains( + $validationMessage, + sprintf('must not be longer than %d characters.', $maxLength), + ); } /** - * @param bool $state + * @Then the :shippingMethod shipping method should be successfully created */ - private function assertShippingMethodState(ShippingMethodInterface $shippingMethod, $state) + public function theShippingMethodShouldBeSuccessfullyCreated(ShippingMethodInterface $shippingMethod): void { - $this->iWantToBrowseShippingMethods(); - - Assert::true($this->indexPage->isSingleResourceOnPage([ - 'name' => $shippingMethod->getName(), - 'enabled' => $state ? 'Enabled' : 'Disabled', - ])); + $this->updatePage->verify(['id' => $shippingMethod->getId()]); + $this->theShipmentMethodShouldAppearInTheRegistry($shippingMethod->getName()); } - protected function resolveCurrentPage(): SymfonyPageInterface + private function assertFieldValidationMessage(string $element, string $expectedMessage): void { - return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); + Assert::same($this->shippingMethodFormElement->getValidationMessage($element), $expectedMessage); } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php index 6e2bf03913..c181989bda 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxRateContext.php @@ -237,7 +237,7 @@ final class ManagingTaxRateContext implements Context */ public function iShouldBeNotifiedThatTaxRateWithThisCodeAlreadyExists() { - Assert::same($this->createPage->getValidationMessage('code'), 'The tax rate with given code already exists.'); + $this->assertFieldValidationMessage('code', 'The tax rate with given code already exists.'); } /** @@ -356,35 +356,6 @@ final class ManagingTaxRateContext implements Context Assert::same($this->indexPage->countItems(), 1); } - /** - * @param string $element - * @param string $taxRateElement - */ - private function assertFieldValue(TaxRateInterface $taxRate, $element, $taxRateElement) - { - $this->indexPage->open(); - - Assert::true( - $this->indexPage->isSingleResourceOnPage([ - 'code' => $taxRate->getCode(), - $element => $taxRateElement, - ]), - sprintf('Tax rate %s %s has not been assigned properly.', $element, $taxRateElement), - ); - } - - /** - * @param string $element - * @param string $expectedMessage - */ - private function assertFieldValidationMessage($element, $expectedMessage) - { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - Assert::same($currentPage->getValidationMessage($element), $expectedMessage); - } - /** * @Given I choose "Included in price" option */ @@ -429,8 +400,29 @@ final class ManagingTaxRateContext implements Context $this->filterElement->filter(); } + private function assertFieldValue(TaxRateInterface $taxRate, string $element, string $taxRateElement): void + { + $this->indexPage->open(); + + Assert::true( + $this->indexPage->isSingleResourceOnPage([ + 'code' => $taxRate->getCode(), + $element => $taxRateElement, + ]), + sprintf('Tax rate %s %s has not been assigned properly.', $element, $taxRateElement), + ); + } + protected function resolveCurrentPage(): SymfonyPageInterface { return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); } + + private function assertFieldValidationMessage(string $element, string $expectedMessage): void + { + /** @var CreatePageInterface|UpdatePageInterface $currentPage */ + $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); + + Assert::same($currentPage->getValidationMessage('field_' . $element), $expectedMessage); + } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php index b5f53a2fa8..54a4ffea7c 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingTaxonsContext.php @@ -16,6 +16,8 @@ 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\Taxon\FormElementInterface; +use Sylius\Behat\Element\Admin\Taxon\ImageFormElementInterface; use Sylius\Behat\NotificationType; use Sylius\Behat\Page\Admin\Product\UpdateSimpleProductPageInterface; use Sylius\Behat\Page\Admin\Taxon\CreateForParentPageInterface; @@ -34,14 +36,16 @@ final class ManagingTaxonsContext implements Context use ValidationTrait; public function __construct( - private SharedStorageInterface $sharedStorage, - private CreatePageInterface $createPage, - private CreateForParentPageInterface $createForParentPage, - private UpdatePageInterface $updatePage, - private CurrentPageResolverInterface $currentPageResolver, - private NotificationCheckerInterface $notificationChecker, - private JavaScriptTestHelper $testHelper, - private UpdateSimpleProductPageInterface $updateSimpleProductPage, + private readonly SharedStorageInterface $sharedStorage, + private readonly CreatePageInterface $createPage, + private readonly CreateForParentPageInterface $createForParentPage, + private readonly UpdatePageInterface $updatePage, + private readonly FormElementInterface $formElement, + private readonly ImageFormElementInterface $imageFormElement, + private readonly CurrentPageResolverInterface $currentPageResolver, + private readonly NotificationCheckerInterface $notificationChecker, + private readonly JavaScriptTestHelper $testHelper, + private readonly UpdateSimpleProductPageInterface $updateSimpleProductPage, ) { } @@ -86,11 +90,9 @@ final class ManagingTaxonsContext implements Context * @When I rename it to :name in :language * @When I do not specify its name */ - public function iNameItIn(?string $name = null, $language = 'en_US') + public function iNameItIn(?string $name = null, $language = 'en_US'): void { - $currentPage = $this->resolveCurrentPage(); - - $currentPage->nameIt($name ?? '', $language); + $this->formElement->nameIt($name ?? '', $language); } /** @@ -98,11 +100,9 @@ final class ManagingTaxonsContext implements Context * @When I do not specify its slug * @When I set its slug to :slug in :language */ - public function iSetItsSlugToIn(?string $slug = null, $language = 'en_US') + public function iSetItsSlugToIn(?string $slug = null, $language = 'en_US'): void { - $currentPage = $this->resolveCurrentPage(); - - $currentPage->specifySlug($slug ?? '', $language); + $this->formElement->slugIt($slug ?? '', $language); } /** @@ -172,10 +172,10 @@ final class ManagingTaxonsContext implements Context /** * @Then /^the ("[^"]+" taxon) should appear in the registry$/ */ - public function theTaxonShouldAppearInTheRegistry(TaxonInterface $taxon) + public function theTaxonShouldAppearInTheRegistry(TaxonInterface $taxon): void { $this->updatePage->open(['id' => $taxon->getId()]); - Assert::true($this->updatePage->hasResourceValues(['code' => $taxon->getCode()])); + Assert::same($this->formElement->getCode(), $taxon->getCode()); } /** @@ -309,9 +309,7 @@ final class ManagingTaxonsContext implements Context */ public function iAttachImageWithType(string $path, ?string $type = null): void { - $currentPage = $this->resolveCurrentPage(); - - $currentPage->attachImage($path, $type); + $this->imageFormElement->attachImage($path, $type); } /** @@ -327,7 +325,7 @@ final class ManagingTaxonsContext implements Context */ public function thisTaxonShouldHaveAnImageWithType(string $type): void { - Assert::true($this->updatePage->isImageWithTypeDisplayed($type)); + Assert::true($this->imageFormElement->isImageWithTypeDisplayed($type)); } /** @@ -335,7 +333,7 @@ final class ManagingTaxonsContext implements Context */ public function thisTaxonShouldNotHaveAnImageWithType($code) { - Assert::false($this->updatePage->isImageWithTypeDisplayed($code)); + Assert::false($this->imageFormElement->isImageWithTypeDisplayed($code)); } /** @@ -343,52 +341,52 @@ final class ManagingTaxonsContext implements Context */ public function iRemoveAnImageWithType(string $type): void { - $this->updatePage->removeImageWithType($type); + $this->imageFormElement->removeImageWithType($type); } /** * @When I remove the first image */ - public function iRemoveTheFirstImage() + public function iRemoveTheFirstImage(): void { - $this->updatePage->removeFirstImage(); + $this->imageFormElement->removeFirstImage(); } /** * @Then /^(this taxon) should not have any images$/ */ - public function thisTaxonShouldNotHaveAnyImages(TaxonInterface $taxon) + public function thisTaxonShouldNotHaveAnyImages(TaxonInterface $taxon): void { $this->iWantToModifyATaxon($taxon); - Assert::same($this->updatePage->countImages(), 0); + Assert::same($this->imageFormElement->countImages(), 0); } /** * @When I change the image with the :type type to :path */ - public function iChangeItsImageToPathForTheType($path, $type) + public function iChangeItsImageToPathForTheType($path, $type): void { - $this->updatePage->changeImageWithType($type, $path); + $this->imageFormElement->changeImageWithType($type, $path); } /** * @When I change the first image type to :type */ - public function iChangeTheFirstImageTypeTo($type) + public function iChangeTheFirstImageTypeTo($type): void { - $this->updatePage->modifyFirstImageType($type); + $this->imageFormElement->modifyFirstImageType($type); } /** * @Then /^(this taxon) should have only one image$/ * @Then /^(this taxon) should(?:| still) have (\d+) images?$/ */ - public function thereShouldStillBeOnlyOneImageInThisTaxon(TaxonInterface $taxon, $count = 1) + public function thereShouldStillBeOnlyOneImageInThisTaxon(TaxonInterface $taxon, $count = 1): void { $this->iWantToModifyATaxon($taxon); - Assert::same($this->updatePage->countImages(), (int) $count); + Assert::same($this->imageFormElement->countImages(), (int) $count); } /** diff --git a/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php b/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php index 5bf6354c3a..b28b46fbd0 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ManagingZonesContext.php @@ -15,27 +15,22 @@ namespace Sylius\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; use Behat\Mink\Exception\ElementNotFoundException; -use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface; -use Sylius\Behat\Context\Ui\Admin\Helper\ValidationTrait; +use Sylius\Behat\Element\Admin\Zone\FormElementInterface; use Sylius\Behat\NotificationType; +use Sylius\Behat\Page\Admin\Crud\CreatePageInterface; use Sylius\Behat\Page\Admin\Crud\IndexPageInterface; -use Sylius\Behat\Page\Admin\Zone\CreatePageInterface; -use Sylius\Behat\Page\Admin\Zone\UpdatePageInterface; +use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface; use Sylius\Behat\Service\NotificationCheckerInterface; -use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface; use Sylius\Component\Addressing\Model\ZoneInterface; -use Sylius\Component\Addressing\Model\ZoneMemberInterface; use Webmozart\Assert\Assert; final class ManagingZonesContext implements Context { - use ValidationTrait; - public function __construct( - private CreatePageInterface $createPage, private IndexPageInterface $indexPage, + private CreatePageInterface $createPage, private UpdatePageInterface $updatePage, - private CurrentPageResolverInterface $currentPageResolver, + private FormElementInterface $formElement, private NotificationCheckerInterface $notificationChecker, ) { } @@ -43,7 +38,7 @@ final class ManagingZonesContext implements Context /** * @When I want to create a new zone consisting of :memberType */ - public function iWantToCreateANewZoneWithMembers($memberType) + public function iWantToCreateANewZoneWithMembers(string $memberType): void { $this->createPage->open(['type' => $memberType]); } @@ -52,7 +47,7 @@ final class ManagingZonesContext implements Context * @When I browse zones * @When I want to see all zones in store */ - public function iWantToSeeAllZonesInStore() + public function iWantToSeeAllZonesInStore(): void { $this->indexPage->open(); } @@ -60,108 +55,88 @@ final class ManagingZonesContext implements Context /** * @When /^I want to modify the (zone named "[^"]+")$/ */ - public function iWantToModifyAZoneNamed(ZoneInterface $zone) + public function iWantToModifyAZoneNamed(ZoneInterface $zone): void { $this->updatePage->open(['id' => $zone->getId()]); } /** - * @When /^I(?:| try to) delete the (zone named "([^"]*)")$/ + * @When /^I(?:| try to) delete the (zone named "([^"]+)")$/ */ - public function iDeleteZoneNamed(ZoneInterface $zone) + public function iDeleteZoneNamed(ZoneInterface $zone): void { $this->indexPage->open(); $this->indexPage->deleteResourceOnPage(['name' => $zone->getName(), 'code' => $zone->getCode()]); } /** - * @When /^I(?:| also) remove (the "([^"]*)" (?:country|province|zone) member)$/ + * @When /^I(?:| also) remove the "([^"]+)" (?:country|province|zone) member$/ + * @When /^I(?:| also) remove the "([^"]+)", "([^"]+)" and "([^"]+)" (?:country|province|zone) members$/ */ - public function iRemoveTheMember(ZoneMemberInterface $zoneMember) + public function iRemoveMembers(string ...$members): void { - $this->updatePage->removeMember($zoneMember); - } - - /** - * @When /^I(?:| also) remove the ("([^"]+)", "([^"]+)" and "([^"]+)" (?:country|province|zone) members)$/ - */ - public function iRemoveMembers(array $countries): void - { - foreach ($countries as $country) { - $this->updatePage->removeMember($country); + foreach ($members as $member) { + $this->formElement->removeMember($member); } } - /** - * @When I rename it to :name - */ - public function iRenameItTo($name) - { - $this->updatePage->nameIt($name ?? ''); - } - /** * @When I name it :name + * @When I rename it to :name + * @When I do not specify its name */ - public function iNameIt($name) + public function iNameIt(string $name = ''): void { - $this->createPage->nameIt($name ?? ''); + $this->formElement->nameIt($name); } /** * @When I specify its code as :code - */ - public function iSpecifyItsCodeAs(?string $code = null): void - { - $this->createPage->specifyCode($code ?? ''); - } - - /** * @When I do not specify its code */ - public function iDoNotSpecifyItsCode() + public function iSpecifyItsCodeAs(string $code = ''): void { - // Intentionally left blank to fulfill context expectation + $this->formElement->specifyCode($code); } /** - * @When I do not specify its name + * @When I specify a too long code */ - public function iDoNotSpecifyItsName() + public function iSpecifyATooLong(): void { - // Intentionally left blank to fulfill context expectation + $this->formElement->specifyCode(str_repeat('a', 256)); } /** * @When I do not add a country member */ - public function iDoNotAddACountryMember() + public function iDoNotAddACountryMember(): void { // Intentionally left blank to fulfill context expectation } /** - * @When /^I add a(?: country| province| zone) "([^"]+)"$/ + * @When /^I add a (?:country|province|zone) "([^"]+)"$/ */ - public function iAddAZoneMember($name) + public function iAddAZoneMember(string $name): void { - $this->createPage->addMember(); - $this->createPage->chooseMember($name); + $this->formElement->addMember(); + $this->formElement->chooseMember($name); } /** * @When I select its scope as :scope */ - public function iSelectItsScopeAs($scope) + public function iSelectItsScopeAs($scope): void { - $this->createPage->selectScope($scope); + $this->formElement->selectScope($scope); } /** * @When I add it * @When I try to add it */ - public function iAddIt() + public function iAddIt(): void { $this->createPage->create(); } @@ -169,7 +144,7 @@ final class ManagingZonesContext implements Context /** * @When I save my changes */ - public function iSaveMyChanges() + public function iSaveMyChanges(): void { $this->updatePage->saveChanges(); } @@ -191,37 +166,53 @@ final class ManagingZonesContext implements Context } /** - * @Then /^the (zone named "[^"]+") with (the "[^"]+" (?:country|province|zone) member) should appear in the registry$/ + * @Then /^the (zone named "[^"]+") with the "([^"]+)" (?:country|province|zone) member should appear in the registry$/ */ - public function theZoneWithTheCountryShouldAppearInTheRegistry(ZoneInterface $zone, ZoneMemberInterface $zoneMember) - { - $this->assertZoneAndItsMember($zone, $zoneMember); + public function theZoneWithTheCountryShouldAppearInTheRegistry( + ZoneInterface $zone, + string $member, + ): void { + $this->updatePage->open(['id' => $zone->getId()]); + + Assert::same($this->formElement->getName(), $zone->getName()); + Assert::true( + $this->formElement->hasMember($member), + sprintf('Zone %s has no member %s', $zone->getName(), $member), + ); } /** * @Given its scope should be :scope */ - public function itsScopeShouldBe($scope) + public function itsScopeShouldBe(string $scope): void { - Assert::same($this->updatePage->getScope(), $scope); + Assert::same($this->formElement->getScope(), $scope); } /** - * @Then /^(this zone) should have only (the "([^"]*)" (?:country|province|zone) member)$/ + * @Then /^(this zone) should have only the "([^"]*)" (?:country|province|zone) member$/ */ - public function thisZoneShouldHaveOnlyTheProvinceMember(ZoneInterface $zone, ZoneMemberInterface $zoneMember) - { - $this->assertZoneAndItsMember($zone, $zoneMember); + public function thisZoneShouldHaveOnlyTheMember( + ZoneInterface $zone, + string $member, + ): void { + $this->updatePage->open(['id' => $zone->getId()]); - Assert::same($this->updatePage->countMembers(), 1); + Assert::same($this->formElement->countMembers(), 1); + Assert::true( + $this->formElement->hasMember($member), + sprintf('Zone %s has no member %s', $zone->getName(), $member), + ); } /** * @Then /^(this zone) name should be "([^"]*)"/ */ - public function thisZoneNameShouldBe(ZoneInterface $zone, $name) + public function thisZoneNameShouldBe(ZoneInterface $zone, string $name): void { - Assert::true($this->updatePage->hasResourceValues(['code' => $zone->getCode(), 'name' => $name])); + $this->updatePage->open(['id' => $zone->getId()]); + + Assert::same($this->formElement->getName(), $name); } /** @@ -229,24 +220,21 @@ final class ManagingZonesContext implements Context */ public function iShouldNotBeAbleToEditItsCode(): void { - Assert::true($this->updatePage->isCodeDisabled()); + Assert::true($this->formElement->isCodeDisabled()); } /** * @Then /^I should be notified that zone with this code already exists$/ */ - public function iShouldBeNotifiedThatZoneWithThisCodeAlreadyExists() + public function iShouldBeNotifiedThatZoneWithThisCodeAlreadyExists(): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - Assert::same($currentPage->getValidationMessage('code'), 'Zone code must be unique.'); + Assert::same($this->formElement->getValidationMessage('code'), 'Zone code must be unique.'); } /** * @Then /^there should still be only one zone with code "([^"]*)"$/ */ - public function thereShouldStillBeOnlyOneZoneWithCode($code) + public function thereShouldStillBeOnlyOneZoneWithCode(string $code): void { $this->indexPage->open(); @@ -256,18 +244,15 @@ final class ManagingZonesContext implements Context /** * @Then I should be notified that :element is required */ - public function iShouldBeNotifiedThatIsRequired($element) + public function iShouldBeNotifiedThatIsRequired(string $element): void { - /** @var CreatePageInterface|UpdatePageInterface $currentPage */ - $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); - - Assert::same($currentPage->getValidationMessage($element), sprintf('Please enter zone %s.', $element)); + Assert::same($this->formElement->getValidationMessage($element), sprintf('Please enter zone %s.', $element)); } /** * @Then zone with :element :value should not be added */ - public function zoneWithNameShouldNotBeAdded($element, $value) + public function zoneWithNameShouldNotBeAdded(string $element, string $value): void { $this->indexPage->open(); @@ -277,9 +262,9 @@ final class ManagingZonesContext implements Context /** * @Then /^I should be notified that at least one zone member is required$/ */ - public function iShouldBeNotifiedThatAtLeastOneZoneMemberIsRequired() + public function iShouldBeNotifiedThatAtLeastOneZoneMemberIsRequired(): void { - Assert::true($this->createPage->checkValidationMessageForMembers('Please add at least 1 zone member.')); + Assert::same($this->formElement->getFormValidationMessage(), 'Please add at least 1 zone member.'); } /** @@ -287,21 +272,24 @@ final class ManagingZonesContext implements Context */ public function iShouldNotBeAbleToEditItsType(): void { - Assert::true($this->createPage->isTypeFieldDisabled()); + Assert::true($this->formElement->isTypeFieldDisabled()); } /** * @Then it should be of :type type */ - public function itShouldBeOfType($type) + public function itShouldBeOfType(string $type): void { - Assert::true($this->createPage->hasType($type)); + Assert::same( + strtolower($this->formElement->getType()), + strtolower($type), + ); } /** * @Then the zone named :zoneName should no longer exist in the registry */ - public function thisZoneShouldNoLongerExistInTheRegistry($zoneName) + public function thisZoneShouldNoLongerExistInTheRegistry(string $zoneName): void { Assert::false($this->indexPage->isSingleResourceOnPage(['name' => $zoneName])); } @@ -318,13 +306,14 @@ final class ManagingZonesContext implements Context /** * @Then /^I should(?:| still) see the (zone named "([^"]+)") in the list$/ */ - public function iShouldSeeTheZoneNamedInTheList(ZoneInterface $zone) + public function iShouldSeeTheZoneNamedInTheList(ZoneInterface $zone): void { Assert::true($this->indexPage->isSingleResourceOnPage(['code' => $zone->getCode(), 'name' => $zone->getName()])); } /** * @Then I should be notified that the zone is in use and cannot be deleted + * @Then I should be notified that this zone cannot be deleted */ public function iShouldBeNotifiedThatTheZoneIsInUseAndCannotBeDeleted(): void { @@ -332,45 +321,29 @@ final class ManagingZonesContext implements Context } /** - * @Then I should be notified that this zone cannot be deleted + * @Then I should be notified that code is too long */ - public function iShouldBeNotifiedThatThisZoneCannotBeDeleted(): void + public function iShouldBeNotifiedThatCodeIsTooLong(): void { - $this->notificationChecker->checkNotification('Error Cannot delete, the zone is in use.', NotificationType::failure()); - } - - /** - * @throws \InvalidArgumentException - */ - private function assertZoneAndItsMember(ZoneInterface $zone, ZoneMemberInterface $zoneMember) - { - Assert::true( - $this->updatePage->hasResourceValues([ - 'code' => $zone->getCode(), - 'name' => $zone->getName(), - ]), - sprintf('Zone %s is not valid', $zone->getName()), + Assert::contains( + $this->formElement->getValidationMessage('code'), + 'must not be longer than 255 characters.', ); - - Assert::true($this->updatePage->hasMember($zoneMember)); } /** - * @Then /^I can not add a(?: country| province| zone) "([^"]+)"$/ + * @Then /^I should not be able to add the "([^"]+)" (?:country|province|zone) as a member$/ */ - public function iCanNotAddAZoneMember($name) + public function iShouldNotBeAbleToAddTheMember(string $name): void { - $member = null; + $this->formElement->addMember(); try { - $member = $this->createPage->chooseMember($name); + $this->formElement->chooseMember($name); } catch (ElementNotFoundException) { + return; } - Assert::isEmpty($member); - } - protected function resolveCurrentPage(): SymfonyPageInterface - { - return $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]); + throw new \InvalidArgumentException(sprintf('Member "%s" should not be selectable.', $name)); } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php b/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php index 2ae6cc8be4..3c4f05cc58 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/NotificationContext.php @@ -14,15 +14,14 @@ declare(strict_types=1); namespace Sylius\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; +use Sylius\Behat\Element\Admin\NotificationsElementInterface; use Sylius\Behat\NotificationType; -use Sylius\Behat\Service\Helper\JavaScriptTestHelperInterface; -use Sylius\Behat\Service\NotificationCheckerInterface; +use Webmozart\Assert\Assert; -final class NotificationContext implements Context +final readonly class NotificationContext implements Context { public function __construct( - private NotificationCheckerInterface $notificationChecker, - private JavaScriptTestHelperInterface $testHelper, + private NotificationsElementInterface $notificationsElement, ) { } @@ -31,11 +30,7 @@ final class NotificationContext implements Context */ public function iShouldBeNotifiedItHasBeenSuccessfullyCreated(): void { - $this->testHelper->waitUntilNotificationPopups( - $this->notificationChecker, - NotificationType::success(), - 'has been successfully created.', - ); + Assert::true($this->notificationsElement->hasNotification((string) NotificationType::success(), 'has been successfully created.')); } /** @@ -45,11 +40,7 @@ final class NotificationContext implements Context */ public function iShouldBeNotifiedThatItHasBeenSuccessfullyEdited(): void { - $this->testHelper->waitUntilNotificationPopups( - $this->notificationChecker, - NotificationType::success(), - 'has been successfully updated.', - ); + Assert::true($this->notificationsElement->hasNotification((string) NotificationType::success(), 'has been successfully updated.')); } /** @@ -58,10 +49,11 @@ final class NotificationContext implements Context */ public function iShouldBeNotifiedThatItHasBeenSuccessfullyDeleted(string $hasHave): void { - $this->testHelper->waitUntilNotificationPopups( - $this->notificationChecker, - NotificationType::success(), - sprintf('%s been successfully deleted.', $hasHave), + Assert::true( + $this->notificationsElement->hasNotification( + (string) NotificationType::success(), + sprintf('%s been successfully deleted.', $hasHave), + ), ); } @@ -70,10 +62,11 @@ final class NotificationContext implements Context */ public function iShouldBeNotifiedThatTheRemovalOperationHasStartedSuccessfully(): void { - $this->testHelper->waitUntilNotificationPopups( - $this->notificationChecker, - NotificationType::success(), - 'has been requested. This process can take a while depending on the number of affected products.', + Assert::true( + $this->notificationsElement->hasNotification( + (string) NotificationType::success(), + 'has been requested. This process can take a while depending on the number of affected products.', + ), ); } @@ -82,10 +75,6 @@ final class NotificationContext implements Context */ public function iShouldBeNotifiedThatItIsInUse(): void { - $this->testHelper->waitUntilNotificationPopups( - $this->notificationChecker, - NotificationType::failure(), - 'Cannot delete', - ); + Assert::true($this->notificationsElement->hasNotification((string) NotificationType::error(), 'Cannot delete')); } } diff --git a/src/Sylius/Behat/Context/Ui/Admin/OrderHistoryContext.php b/src/Sylius/Behat/Context/Ui/Admin/OrderHistoryContext.php new file mode 100644 index 0000000000..70c924090f --- /dev/null +++ b/src/Sylius/Behat/Context/Ui/Admin/OrderHistoryContext.php @@ -0,0 +1,51 @@ +historyPage->open(['id' => $order->getId()]); + } + + /** + * @Then there should be :count shipping address changes in the registry + */ + public function thereShouldBeCountShippingAddressChangesInTheRegistry(int $count): void + { + Assert::same($this->historyPage->countShippingAddressChanges(), $count); + } + + /** + * @Then there should be :count billing address changes in the registry + */ + public function thereShouldBeCountBillingAddressChangesInTheRegistry(int $count): void + { + Assert::same($this->historyPage->countBillingAddressChanges(), $count); + } +} diff --git a/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php b/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php index 88f68e2cca..ecdd5c1b3e 100644 --- a/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php +++ b/src/Sylius/Behat/Context/Ui/Admin/ProductShowPageContext.php @@ -114,7 +114,7 @@ final class ProductShowPageContext implements Context public function iAccessThePriceHistoryIndexPageOfSimpleProductForChannel(string $channelName): void { $pricingRow = $this->pricingElement->getSimpleProductPricingRowForChannel($channelName); - $pricingRow->clickLink('Show'); + $pricingRow->find('css', '[data-test-price-history]')->click(); } /** @@ -123,7 +123,7 @@ final class ProductShowPageContext implements Context public function iAccessThePriceHistoryIndexPageOfVariantForChannel(string $variantName, string $channelName): void { $pricingRow = $this->pricingElement->getVariantPricingRowForChannel($variantName, $channelName); - $pricingRow->clickLink('Show'); + $pricingRow->find('css', '[data-test-price-history]')->click(); } /** diff --git a/src/Sylius/Behat/Context/Ui/CustomerContext.php b/src/Sylius/Behat/Context/Ui/CustomerContext.php index 997214bfa9..c81a6c515d 100644 --- a/src/Sylius/Behat/Context/Ui/CustomerContext.php +++ b/src/Sylius/Behat/Context/Ui/CustomerContext.php @@ -54,6 +54,6 @@ final class CustomerContext implements Context $this->customerShowPage->open(['id' => $deletedUser->getCustomer()->getId()]); - Assert::false($this->customerShowPage->isRegistered()); + Assert::false($this->customerShowPage->hasAccount()); } } diff --git a/src/Sylius/Behat/Context/Ui/ThemeContext.php b/src/Sylius/Behat/Context/Ui/ThemeContext.php index bc3b95b2d4..8406ef3bcc 100644 --- a/src/Sylius/Behat/Context/Ui/ThemeContext.php +++ b/src/Sylius/Behat/Context/Ui/ThemeContext.php @@ -51,7 +51,7 @@ final class ThemeContext implements Context public function iUnsetThemeOnChannel(ChannelInterface $channel) { $this->channelUpdatePage->open(['id' => $channel->getId()]); - $this->channelUpdatePage->unsetTheme(); + $this->channelUpdatePage->setTheme(''); $this->channelUpdatePage->saveChanges(); } diff --git a/src/Sylius/Behat/Context/Ui/UserContext.php b/src/Sylius/Behat/Context/Ui/UserContext.php index 53acd1af67..27c6d0fe5c 100644 --- a/src/Sylius/Behat/Context/Ui/UserContext.php +++ b/src/Sylius/Behat/Context/Ui/UserContext.php @@ -62,6 +62,6 @@ final class UserContext implements Context $this->customerShowPage->open(['id' => $deletedUser->getCustomer()->getId()]); - Assert::false($this->customerShowPage->isRegistered()); + Assert::false($this->customerShowPage->hasAccount()); } } diff --git a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php index 7bfeb5c9ad..2abc4ef87d 100644 --- a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php +++ b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElement.php @@ -14,14 +14,21 @@ declare(strict_types=1); namespace Sylius\Behat\Element\Admin\CatalogPromotion; use Behat\Mink\Element\NodeElement; -use Behat\Mink\Exception\ElementNotFoundException; -use FriendsOfBehat\PageObjectExtension\Element\Element; +use Behat\Mink\Session; +use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Behat\Service\TabsHelper; -use Sylius\Component\Core\Model\ChannelInterface; -use Webmozart\Assert\Assert; -final class FormElement extends Element implements FormElementInterface +final class FormElement extends BaseFormElement implements FormElementInterface { + public function __construct( + Session $session, + $minkParameters, + private readonly AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters); + } + public function nameIt(string $name): void { $this->getElement('name')->setValue($name); @@ -29,12 +36,12 @@ final class FormElement extends Element implements FormElementInterface public function labelIt(string $label, string $localeCode): void { - $this->getElement('label', ['%localeCode%' => $localeCode])->setValue($label); + $this->getElement('label', ['%locale_code%' => $localeCode])->setValue($label); } public function describeIt(string $description, string $localeCode): void { - $this->getElement('description', ['%localeCode%' => $localeCode])->setValue($description); + $this->getElement('description', ['%locale_code%' => $localeCode])->setValue($description); } public function prioritizeIt(int $priority): void @@ -49,7 +56,7 @@ final class FormElement extends Element implements FormElementInterface public function checkChannel(string $channelName): void { - $this->getDocument()->checkField($channelName); + $this->getElement('channels')->checkField($channelName); } public function setExclusiveness(bool $isExclusive): void @@ -59,190 +66,158 @@ final class FormElement extends Element implements FormElementInterface public function uncheckChannel(string $channelName): void { - $this->getDocument()->uncheckField($channelName); + $this->getElement('channels')->uncheckField($channelName); } public function specifyStartDate(\DateTimeInterface $startDate): void { $timestamp = $startDate->getTimestamp(); - $this->getElement('start_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('start_date_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('start_date_time')->setValue(date('H:i', $timestamp)); } public function specifyEndDate(\DateTimeInterface $endDate): void { $timestamp = $endDate->getTimestamp(); - $this->getElement('end_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('end_date_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('end_date_time')->setValue(date('H:i', $timestamp)); } - public function addScope(): void + public function addScope(string $type): void { - $this->addCollectionElement('scopes', 'add_scope_button'); + $this->getElement('add_scope_button', ['%type%' => $type])->press(); + $this->waitForFormUpdate(); } - public function addAction(): void + public function addAction(string $type): void { - $this->addCollectionElement('actions', 'add_action_button'); + $this->getElement('add_action_button', ['%type%' => $type])->press(); + $this->waitForFormUpdate(); } - public function chooseScopeType(string $type): void + public function selectScopeOption(array $values): void { $lastScope = $this->getElement('last_scope'); + foreach ($values as $value) { + $this->autocompleteHelper->selectByValue( + $this->getDriver(), + $lastScope->find('css', 'select')->getXpath(), + $value, + ); + } - $lastScope->selectFieldOption('Type', $type); + $this->waitForFormUpdate(); } - public function chooseActionType(string $type): void + public function fillActionOption(string $option, string $value): void { $lastAction = $this->getElement('last_action'); - $lastAction->selectFieldOption('Type', $type); + $lastAction->fillField($option, $value); } - public function chooseLastScopeCodes(array $codes): void - { - $lastScope = $this->getElement('last_scope'); - - $lastScope->find('css', 'input[type="hidden"]')->setValue(implode(',', $codes)); - } - - public function specifyLastActionDiscount(string $discount): void + public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void { $lastAction = $this->getElement('last_action'); - $lastAction->find('css', 'input')->setValue($discount); - } + TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode); - public function specifyLastActionDiscountForChannel(string $discount, ChannelInterface $channel): void - { - $lastAction = $this->getElement('last_action'); - - TabsHelper::switchTab($this->getSession(), $lastAction, $channel->getCode()); - - $lastAction->find('css', sprintf('[id$="%s_amount"]', $channel->getCode()))->setValue($discount); - } - - public function getFieldValueInLocale(string $field, string $localeCode): string - { - return $this->getElement($field, ['%localeCode%' => $localeCode])->getValue(); + $lastAction->find('css', sprintf('[id$="_configuration_%s"]', $channelCode))->fillField($option, $value); } public function getLastScopeCodes(): array { $lastScope = $this->getElement('last_scope'); - return explode(',', $lastScope->find('css', 'input[type="hidden"]')->getValue()); + return array_map( + fn (NodeElement $element) => $element->getValue(), + $lastScope->findAll('css', 'option[selected="selected"]'), + ); } - public function getLastActionDiscount(): string + public function getLastActionOption(string $option): string { $lastAction = $this->getElement('last_action'); - return $lastAction->find('css', 'input')->getValue(); + return $lastAction->findField($option)->getValue(); } - public function getLastActionFixedDiscount(ChannelInterface $channel): string + public function getLastActionOptionForChannel(string $channelCode, string $option): string { $lastAction = $this->getElement('last_action'); - TabsHelper::switchTab($this->getSession(), $lastAction, $channel->getCode()); + TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode); - return $lastAction->find('css', sprintf('[id$="%s_amount"]', $channel->getCode()))->getValue(); + return $lastAction->find('css', sprintf('[id$="_configuration_%s"]', $channelCode))->findField($option)->getValue(); } - public function getValidationMessage(): string + public function checkIfScopeConfigurationFormIsVisible(): bool { - $foundElement = $this->getDocument()->find('css', '.sylius-validation-error'); - - if (null === $foundElement) { - throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error'); - } - - return $foundElement->getText(); + return $this->hasElement('last_scope'); } - public function hasValidationMessage(string $message): bool + public function checkIfActionConfigurationFormIsVisible(): bool { - $validationElements = $this->getDocument()->findAll('css', '.sylius-validation-error'); - - foreach ($validationElements as $validationElement) { - if ($validationElement->getText() === $message) { - return true; - } - } - - return false; + return $this->hasElement('last_action'); } - public function hasOnlyOneValidationMessage(string $message): bool + public function getFieldValueInLocale(string $field, string $localeCode): string { - $validationElements = $this->getDocument()->findAll('css', '.sylius-validation-error'); - - $counter = 0; - foreach ($validationElements as $validationElement) { - if ($validationElement->getText() === $message) { - ++$counter; - } - } - - return $counter === 1; + return $this->getElement($field, ['%locale_code%' => $localeCode])->getValue(); } - public function removeAllActions(): void + public function getValidationMessages(): array { - $deleteButtons = $this->getDocument()->findAll('css', '#actions [data-form-collection="delete"]'); + $errors = $this->getElement('form')->findAll('css', '.alert-danger'); - foreach ($deleteButtons as $deleteButton) { - $deleteButton->click(); - } + return array_map(fn (NodeElement $element) => $element->getText(), $errors); } - public function removeAllScopes(): void + public function removeScopeOption(array $values): void { - $deleteButtons = $this->getDocument()->findAll('css', '#scopes [data-form-collection="delete"]'); - - foreach ($deleteButtons as $deleteButton) { - $deleteButton->click(); + $lastScope = $this->getElement('last_scope'); + foreach ($values as $value) { + $this->autocompleteHelper->removeByValue( + $this->getDriver(), + $lastScope->find('css', 'select')->getXpath(), + $value, + ); } + + $this->waitForFormUpdate(); + } + + public function removeLastAction(): void + { + $this->getElement('last_action')->find('css', '[data-test-delete-action]')->click(); + } + + public function removeLastScope(): void + { + $this->getElement('last_scope')->find('css', '[data-test-delete-action]')->click(); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'actions' => '#actions', - 'add_action_button' => '#actions [data-form-collection="add"]', - 'add_scope_button' => '#scopes [data-form-collection="add"]', - 'description' => '#sylius_catalog_promotion_translations_%localeCode%_description', + 'add_action_button' => '[data-test-actions] [data-test-add-%type%]', + 'add_scope_button' => '[data-test-scopes] [data-test-add-%type%]', + 'channels' => '#sylius_catalog_promotion_channels', + 'description' => '[name="sylius_catalog_promotion[translations][%locale_code%][description]"]', 'enabled' => '#sylius_catalog_promotion_enabled', + 'end_date_date' => '#sylius_catalog_promotion_endDate_date', + 'end_date_time' => '#sylius_catalog_promotion_endDate_time', 'exclusive' => '#sylius_catalog_promotion_exclusive', - 'end_date' => '#sylius_catalog_promotion_endDate_date', - 'label' => '#sylius_catalog_promotion_translations_%localeCode%_label', - 'last_action' => '#actions [data-form-collection="item"]:last-child', - 'last_scope' => '#scopes [data-form-collection="item"]:last-child', + 'form' => '[data-live-name-value="sylius_admin:catalog_promotion:form"]', + 'label' => '[name="sylius_catalog_promotion[translations][%locale_code%][label]"]', + 'last_action' => '[data-test-actions] [data-test-entry-row]:last-child', + 'last_scope' => '[data-test-scopes] [data-test-entry-row]:last-child', 'name' => '#sylius_catalog_promotion_name', 'priority' => '#sylius_catalog_promotion_priority', - 'scopes' => '#scopes', - 'start_date' => '#sylius_catalog_promotion_startDate_date', + 'start_date_date' => '#sylius_catalog_promotion_startDate_date', + 'start_date_time' => '#sylius_catalog_promotion_startDate_time', ]); } - - private function addCollectionElement(string $collectionElement, string $buttonElement): void - { - $count = count($this->getCollectionItems($collectionElement)); - - $this->getElement($buttonElement)->click(); - - $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems($collectionElement))); - } - - /** @return NodeElement[] */ - private function getCollectionItems(string $collection): array - { - $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]'); - - Assert::isArray($items); - - return $items; - } } diff --git a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php index de218c0ecd..c2a02f4040 100644 --- a/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php +++ b/src/Sylius/Behat/Element/Admin/CatalogPromotion/FormElementInterface.php @@ -13,9 +13,9 @@ declare(strict_types=1); namespace Sylius\Behat\Element\Admin\CatalogPromotion; -use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface; -interface FormElementInterface +interface FormElementInterface extends BaseFormElementInterface { public function nameIt(string $name): void; @@ -37,33 +37,33 @@ interface FormElementInterface public function specifyEndDate(\DateTimeInterface $endDate): void; - public function addScope(): void; + public function addScope(string $type): void; - public function addAction(): void; + public function addAction(string $type): void; - public function chooseScopeType(string $type): void; + public function selectScopeOption(array $values): void; - public function chooseActionType(string $type): void; + public function fillActionOption(string $option, string $value): void; - public function chooseLastScopeCodes(array $codes): void; - - public function specifyLastActionDiscount(string $discount): void; - - public function specifyLastActionDiscountForChannel(string $discount, ChannelInterface $channel): void; - - public function getFieldValueInLocale(string $field, string $localeCode): string; + public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void; public function getLastScopeCodes(): array; - public function getLastActionDiscount(): string; + public function getLastActionOption(string $option): string; - public function getLastActionFixedDiscount(ChannelInterface $channel): string; + public function getLastActionOptionForChannel(string $channelCode, string $option): string; - public function getValidationMessage(): string; + public function getFieldValueInLocale(string $field, string $localeCode): string; - public function hasValidationMessage(string $message): bool; + public function checkIfScopeConfigurationFormIsVisible(): bool; - public function removeAllActions(): void; + public function checkIfActionConfigurationFormIsVisible(): bool; - public function removeAllScopes(): void; + public function getValidationMessages(): array; + + public function removeScopeOption(array $values): void; + + public function removeLastAction(): void; + + public function removeLastScope(): void; } diff --git a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php index 88db93d230..fa8399fc1d 100644 --- a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php +++ b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElement.php @@ -13,37 +13,59 @@ declare(strict_types=1); namespace Sylius\Behat\Element\Admin\Channel; -use FriendsOfBehat\PageObjectExtension\Element\Element; -use Sylius\Behat\Service\AutocompleteHelper; +use Behat\Mink\Session; +use FriendsOfBehat\SymfonyExtension\Mink\MinkParameters; +use Sylius\Behat\Element\Admin\Crud\FormElement as BaseFormElement; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Component\Core\Model\TaxonInterface; -final class ExcludeTaxonsFromShowingLowestPriceInputElement extends Element implements ExcludeTaxonsFromShowingLowestPriceInputElementInterface +final class ExcludeTaxonsFromShowingLowestPriceInputElement extends BaseFormElement implements ExcludeTaxonsFromShowingLowestPriceInputElementInterface { + public function __construct( + Session $session, + array|MinkParameters $minkParameters, + private AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters); + } + public function excludeTaxon(TaxonInterface $taxon): void { - $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price')->getParent(); + $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price'); - AutocompleteHelper::chooseValue($this->getSession(), $excludeTaxonElement, $taxon->getName()); + $this->autocompleteHelper->selectByValue( + $this->getDriver(), + $excludeTaxonElement->getXpath(), + $taxon->getCode(), + ); + $this->waitForFormUpdate(); } public function removeExcludedTaxon(TaxonInterface $taxon): void { - $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price')->getParent(); + $excludeTaxonElement = $this->getElement('taxons_excluded_from_showing_lowest_price'); - AutocompleteHelper::removeValue($this->getSession(), $excludeTaxonElement, $taxon->getName()); + $this->autocompleteHelper->removeByValue( + $this->getDriver(), + $excludeTaxonElement->getXpath(), + $taxon->getCode(), + ); + $this->waitForFormUpdate(); } public function hasTaxonExcluded(TaxonInterface $taxon): bool { - $excludedTaxons = $this->getElement('taxons_excluded_from_showing_lowest_price')->getValue(); - - return str_contains($excludedTaxons, $taxon->getCode()); + return null !== $this + ->getElement('taxons_excluded_from_showing_lowest_price') + ->find('css', sprintf('option:selected:contains("%s")', $taxon->getName())) + ; } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'taxons_excluded_from_showing_lowest_price' => '#sylius_channel_channelPriceHistoryConfig_taxonsExcludedFromShowingLowestPrice', + 'form' => 'form', + 'taxons_excluded_from_showing_lowest_price' => '[data-test-taxons-excluded-from-showing-lowest-price]', ]); } } diff --git a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php index 06651abd80..865999e622 100644 --- a/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php +++ b/src/Sylius/Behat/Element/Admin/Channel/ExcludeTaxonsFromShowingLowestPriceInputElementInterface.php @@ -21,5 +21,5 @@ interface ExcludeTaxonsFromShowingLowestPriceInputElementInterface public function removeExcludedTaxon(TaxonInterface $taxon): void; - public function hasTaxonExcluded(TaxonInterface $taxons): bool; + public function hasTaxonExcluded(TaxonInterface $taxon): bool; } diff --git a/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php b/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php index ffbbb46b7c..2ef1b4a74f 100644 --- a/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php +++ b/src/Sylius/Behat/Element/Admin/Channel/LowestPriceFlagElement.php @@ -35,7 +35,7 @@ final class LowestPriceFlagElement extends Element implements LowestPriceFlagEle protected function getDefinedElements(): array { return [ - 'lowest_price_for_discounted_products_visible' => '#sylius_channel_channelPriceHistoryConfig_lowestPriceForDiscountedProductsVisible', + 'lowest_price_for_discounted_products_visible' => '[data-test-lowest-price-for-discounted-products-visible]', ]; } } diff --git a/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php b/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php index 2746772a5d..30343137b6 100644 --- a/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php +++ b/src/Sylius/Behat/Element/Admin/Channel/ShippingAddressInCheckoutRequiredElement.php @@ -13,49 +13,80 @@ declare(strict_types=1); namespace Sylius\Behat\Element\Admin\Channel; +use Behat\Mink\Element\NodeElement; use FriendsOfBehat\PageObjectExtension\Element\Element; +use Webmozart\Assert\Assert; final class ShippingAddressInCheckoutRequiredElement extends Element implements ShippingAddressInCheckoutRequiredElementInterface { + private const ADDRESS_TYPE_BILLING = 'billing'; + + private const ADDRESS_TYPE_SHIPPING = 'shipping'; + public function requireShippingAddressInCheckout(): void { - $this->getElement('shipping_address_in_checkout_required')->check(); + $this->requireAddressTypeInCheckout(self::ADDRESS_TYPE_SHIPPING); } public function requireBillingAddressInCheckout(): void { - $this->getElement('shipping_address_in_checkout_required')->uncheck(); + $this->requireAddressTypeInCheckout(self::ADDRESS_TYPE_BILLING); } public function requireAddressTypeInCheckout(string $type): void { - if ($type === 'shipping') { - $this->requireShippingAddressInCheckout(); - - return; - } - - $this->requireBillingAddressInCheckout(); + $this->getChoiceForAddressType($type)->click(); } public function isShippingAddressInCheckoutRequired(): bool { - return $this->getElement('shipping_address_in_checkout_required')->isChecked(); + return self::ADDRESS_TYPE_SHIPPING === $this->getRequiredAddressTypeInCheckout(); } public function getRequiredAddressTypeInCheckout(): string { - if ($this->isShippingAddressInCheckoutRequired()) { - return 'shipping'; + foreach ($this->getChoices() as $type => $choice) { + if ($choice->isChecked()) { + return $type; + } } - return 'billing'; + throw new \InvalidArgumentException('No address type selected.'); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'shipping_address_in_checkout_required' => '#sylius_channel_shippingAddressInCheckoutRequired', + 'shipping_address_in_checkout_required' => '[data-test-shipping-address-in-checkout-required]', ]); } + + private function getChoiceForAddressType(string $type): NodeElement + { + $choices = $this->getChoices(); + Assert::keyExists($choices, $type); + + return $choices[$type]; + } + + /** @return array */ + private function getChoices(): array + { + $element = $this->getElement('shipping_address_in_checkout_required'); + $labelsElements = $element->findAll('css', 'label'); + + $choices = []; + foreach ($labelsElements as $labelElement) { + $label = strtolower($labelElement->getText()); + foreach ([self::ADDRESS_TYPE_BILLING, self::ADDRESS_TYPE_SHIPPING] as $type) { + if (str_contains($label, $type)) { + $choices[$type] = $element->findById($labelElement->getAttribute('for')); + + continue 2; + } + } + } + + return $choices; + } } diff --git a/src/Sylius/Behat/Element/Admin/Crud/FormElement.php b/src/Sylius/Behat/Element/Admin/Crud/FormElement.php new file mode 100644 index 0000000000..4adc75c6c0 --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/Crud/FormElement.php @@ -0,0 +1,56 @@ +getFieldElement($element, $parameters); + if (null === $foundElement) { + throw new ElementNotFoundException($this->getSession(), 'Field element'); + } + + $validationMessage = $foundElement->find('css', '.invalid-feedback'); + if (null === $validationMessage) { + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); + } + + return $validationMessage->getText(); + } + + protected function waitForFormUpdate(): void + { + $form = $this->getElement('form'); + usleep(500000); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute + $form->waitFor(1500, function () use ($form) { + return !$form->hasAttribute('busy'); + }); + } + + /** @throws ElementNotFoundException */ + private function getFieldElement(string $element, array $parameters): ?NodeElement + { + $element = $this->getElement($element, $parameters); + while (null !== $element && !$element->hasClass('field')) { + $element = $element->getParent(); + } + + return $element; + } +} diff --git a/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php new file mode 100644 index 0000000000..819ae4c47a --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/Crud/FormElementInterface.php @@ -0,0 +1,22 @@ +getElement('flashes_container'); + + if (DriverHelper::isJavascript($this->getDriver())) { + $flashesContainer->waitFor(5, function () use ($flashesContainer) { + return $flashesContainer->isVisible(); + }); + } + + /** @var array $flashes */ + $flashes = $flashesContainer->findAll('css', '[data-test-sylius-flash-message]'); + + foreach ($flashes as $flash) { + if (str_contains($flash->getText(), $message) && $flash->getAttribute('data-test-sylius-flash-message-type') === $type) { + return true; + } + } + + return false; + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'flashes_container' => '[data-test-sylius-flashes-container]', + ]); + } +} diff --git a/src/Sylius/Behat/Element/Admin/NotificationsElementInterface.php b/src/Sylius/Behat/Element/Admin/NotificationsElementInterface.php new file mode 100644 index 0000000000..5cbdafc6c2 --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/NotificationsElementInterface.php @@ -0,0 +1,19 @@ +getElement('code')->setValue($code); + } + + public function setName(string $name, string $localeCode): void + { + $this->getElement('name', ['%locale%' => $localeCode])->setValue($name); + } + + protected function getCodeElement(): NodeElement + { + return $this->getElement('code'); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'code' => '[data-test-code]', + 'name' => '[data-test-name="%locale%"]', + ]); + } +} diff --git a/src/Sylius/Behat/Element/Admin/ProductAssociationType/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/ProductAssociationType/FormElementInterface.php new file mode 100644 index 0000000000..4eff5afcee --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/ProductAssociationType/FormElementInterface.php @@ -0,0 +1,25 @@ +getElement('priority')->getValue(); + } + + public function setPriority(?int $priority): void { $this->getElement('priority')->setValue($priority); } + public function setStartsAt(\DateTimeInterface $dateTime): void + { + $timestamp = $dateTime->getTimestamp(); + + $this->getElement('starts_at_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('starts_at_time')->setValue(date('H:i', $timestamp)); + } + + public function setEndsAt(\DateTimeInterface $dateTime): void + { + $timestamp = $dateTime->getTimestamp(); + + $this->getElement('ends_at_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('ends_at_time')->setValue(date('H:i', $timestamp)); + } + + public function setUsageLimit(int $limit): void + { + $this->getElement('usage_limit')->setValue($limit); + } + + public function makeExclusive(): void + { + $this->getElement('exclusive')->check(); + } + + public function makeNotAppliesToDiscountedItem(): void + { + $this->getElement('applies_to_discounted')->uncheck(); + } + + public function makeCouponBased(): void + { + $this->getElement('coupon_based')->check(); + } + + public function checkChannel(string $name): void + { + $this->getElement('channels')->checkField($name); + } + + public function setLabel(string $label, string $localeCode): void + { + $this->getElement('label', ['%locale_code%' => $localeCode])->setValue($label); + } + + public function hasLabel(string $label, string $localeCode): bool + { + return $label === $this->getElement('label', ['%locale_code%' => $localeCode])->getValue(); + } + + public function addAction(string $type): void + { + $this->getElement('add_action_button', ['%type%' => $type])->press(); + $this->waitForFormUpdate(); + } + + public function removeLastAction(): void + { + $this->getLastAction()->find('css', 'button[data-test-delete]')->press(); + $this->waitForFormUpdate(); + } + + public function fillActionOption(string $option, string $value): void + { + $this->getLastAction()->fillField($option, $value); + } + + public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void + { + $lastAction = $this->getChannelConfigurationOfLastAction($channelCode); + $lastAction->fillField($option, $value); + } + + public function selectActionOption(string $option, string $value, bool $multiple = false): void + { + $this->getLastAction()->find('named', ['select', $option])->selectOption($value, $multiple); + } + + public function addRule(string $type): void + { + $this->getElement('add_rule_button', ['%type%' => $type])->press(); + $this->waitForFormUpdate(); + } + + public function removeLastRule(): void + { + $this->getLastRule()->find('css', 'button[data-test-delete]')->press(); + $this->waitForFormUpdate(); + } + + public function selectRuleOption(string $option, string $value, bool $multiple = false): void + { + $this->getLastRule()->find('named', ['select', $option])->selectOption($value, $multiple); + } + + public function fillRuleOption(string $option, string $value): void + { + $this->getLastRule()->fillField($option, $value); + } + + public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void + { + $lastRule = $this->getChannelConfigurationOfLastRule($channelCode); + $lastRule->fillField($option, $value); + } + + public function selectAutocompleteRuleOptions(array $values, ?string $channelCode = null): void + { + $count = count($this->getElement('rules')->findAll('css', '[data-test-entry-row]')); + $locator = $channelCode ? + sprintf('#sylius_promotion_rules_%d_configuration_%s select', $count - 1, $channelCode) : + sprintf('#sylius_promotion_rules_%d_configuration select', $count - 1) + ; + foreach ($values as $value) { + $this->autocompleteHelper->selectByName( + $this->getDriver(), + $this->getLastRule()->find('css', $locator)->getXpath(), + $value, + ); + } + + $this->waitForFormUpdate(); + } + + public function selectAutocompleteActionFilterOptions(array $values, string $channelCode, string $filterType): void + { + $count = count($this->getElement('actions')->findAll('css', '[data-test-entry-row]')); + $locator = sprintf('#sylius_promotion_actions_%d_configuration_%s_filters_%s_filter select', $count - 1, $channelCode, $filterType); + foreach ($values as $value) { + $this->autocompleteHelper->selectByName( + $this->getDriver(), + $this->getLastAction()->find('css', $locator)->getXpath(), + $value, + ); + } + + $this->waitForFormUpdate(); + } + + public function checkIfRuleConfigurationFormIsVisible(): bool + { + return $this->hasElement('rule_count'); + } + + public function checkIfActionConfigurationFormIsVisible(): bool + { + return $this->hasElement('action_amount'); + } + + public function getValidationMessageForAction(): string + { + $actionForm = $this->getLastAction(); + + $foundElement = $actionForm->find('css', '.invalid-feedback'); + if (null === $foundElement) { + throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.invalid-feedback'); + } + + return $foundElement->getText(); + } + + public function getValidationMessageForTranslation(string $element, string $localeCode): string + { + $foundElement = $this->getElement($element, ['%locale_code%' => $localeCode])->getParent(); + + $validationMessage = $foundElement->find('css', '.invalid-feedback'); + if (null === $validationMessage) { + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); + } + + return $validationMessage->getText(); + } + protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ + 'action_amount' => '#sylius_promotion_actions_0_configuration_WEB-US_amount', + 'actions' => '#sylius_promotion_actions', + 'add_action_button' => '[data-test-actions] [data-test-add-%type%]', + 'add_rule_button' => '[data-test-rules] [data-test-add-%type%]', + 'applies_to_discounted' => '#sylius_promotion_appliesToDiscounted', + 'channels' => '#sylius_promotion_channels', + 'code' => '#sylius_promotion_code', + 'coupon_based' => '#sylius_promotion_couponBased', + 'ends_at_date' => '#sylius_promotion_endsAt_date', + 'ends_at_time' => '#sylius_promotion_endsAt_time', + 'exclusive' => '#sylius_promotion_exclusive', + 'form' => '[data-live-name-value="sylius_admin:promotion:form"]', + 'label' => '[name="sylius_promotion[translations][%locale_code%][label]"]', + 'last_action' => '[data-test-actions] [data-test-entry-row]:last-child', + 'last_rule' => '[data-test-rules] [data-test-entry-row]:last-child', + 'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min', + 'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max', + 'name' => '#sylius_promotion_name', 'priority' => '#sylius_promotion_priority', + 'rule_count' => '#sylius_promotion_rules_0_configuration_count', + 'rules' => '#sylius_promotion_rules', + 'starts_at_date' => '#sylius_promotion_startsAt_date', + 'starts_at_time' => '#sylius_promotion_startsAt_time', + 'translation_tab' => '[data-test-promotion-translations-accordion="%locale_code%"]', + 'usage_limit' => '#sylius_promotion_usageLimit', ]); } + + private function getLastAction(): NodeElement + { + return $this->getElement('last_action'); + } + + private function getChannelConfigurationOfLastAction(string $channelCode): NodeElement + { + $lastAction = $this->getLastAction(); + + TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode); + + return $lastAction + ->find('css', sprintf('[id^="sylius_promotion_actions_"][id$="_configuration_%s"]', $channelCode)) + ; + } + + private function getLastRule(): NodeElement + { + return $this->getElement('last_rule'); + } + + private function getChannelConfigurationOfLastRule(string $channelCode): NodeElement + { + $lastRule = $this->getLastRule(); + + TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode); + + return $lastRule->find( + 'css', + sprintf('[id^="sylius_promotion_rules_"][id$="_configuration_%s"]', $channelCode), + ); + } } diff --git a/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php index 55c792c454..f7076bee1b 100644 --- a/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php +++ b/src/Sylius/Behat/Element/Admin/Promotion/FormElementInterface.php @@ -13,7 +13,61 @@ declare(strict_types=1); namespace Sylius\Behat\Element\Admin\Promotion; -interface FormElementInterface +use Sylius\Behat\Element\Admin\Crud\FormElementInterface as BaseFormElementInterface; + +interface FormElementInterface extends BaseFormElementInterface { - public function prioritizeIt(?int $priority): void; + public function setPriority(?int $priority): void; + + public function getPriority(): int; + + public function setStartsAt(\DateTimeInterface $dateTime): void; + + public function setEndsAt(\DateTimeInterface $dateTime): void; + + public function setUsageLimit(int $limit): void; + + public function makeExclusive(): void; + + public function makeNotAppliesToDiscountedItem(): void; + + public function makeCouponBased(): void; + + public function checkChannel(string $name): void; + + public function setLabel(string $label, string $localeCode): void; + + public function hasLabel(string $label, string $localeCode): bool; + + public function addAction(string $type): void; + + public function removeLastAction(): void; + + public function fillActionOption(string $option, string $value): void; + + public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void; + + public function selectActionOption(string $option, string $value, bool $multiple = false): void; + + public function addRule(string $type): void; + + public function removeLastRule(): void; + + public function selectRuleOption(string $option, string $value, bool $multiple = false): void; + + public function fillRuleOption(string $option, string $value): void; + + public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void; + + public function selectAutocompleteRuleOptions(array $values, ?string $channelCode = null): void; + + public function selectAutocompleteActionFilterOptions(array $values, string $channelCode, string $filterType): void; + + public function checkIfRuleConfigurationFormIsVisible(): bool; + + public function checkIfActionConfigurationFormIsVisible(): bool; + + public function getValidationMessageForAction(): string; + + public function getValidationMessageForTranslation(string $element, string $localeCode): string; } diff --git a/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElement.php b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElement.php new file mode 100644 index 0000000000..c3e4f77f71 --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElement.php @@ -0,0 +1,179 @@ +getElement('code')->getValue(); + } + + public function setCode(string $code): void + { + $this->getElement('code')->setValue($code); + } + + public function isCodeDisabled(): bool + { + return $this->getElement('code')->hasAttribute('disabled'); + } + + public function getName(string $localeCode = 'en_US') + { + return $this->getElement('name', ['%localeCode%' => $localeCode])->getValue(); + } + + public function setName(string $name, string $localeCode = 'en_US'): void + { + $this->getElement('name', ['%localeCode%' => $localeCode])->setValue($name); + } + + public function getPosition(): int + { + return (int) $this->getElement('position')->getValue(); + } + + public function setPosition(int $position): void + { + $this->getElement('position')->setValue($position); + } + + public function getDescription(string $localeCode = 'en_US'): string + { + return $this->getElement('description', ['%localeCode%' => $localeCode])->getValue(); + } + + public function setDescription(string $description, string $localeCode = 'en_US'): void + { + $this->getElement('description', ['%localeCode%' => $localeCode])->setValue($description); + } + + public function getZoneCode(): string + { + return $this->getElement('zone')->getValue(); + } + + public function setZoneCode(string $code): void + { + $this->getElement('zone')->setValue($code); + } + + public function disable(): void + { + $this->getElement('enabled')->uncheck(); + } + + public function enable(): void + { + $this->getElement('enabled')->check(); + } + + public function checkChannel(string $channelCode): void + { + $this->getElement('channel', ['%channelCode%' => $channelCode])->check(); + } + + public function hasCheckedChannel(string $channelCode): bool + { + return $this->getElement('channel', ['%channelCode%' => $channelCode])->isChecked(); + } + + public function setCalculatorConfigurationAmountForChannel(string $channelCode, ?int $amount): void + { + $this->selectCalculatorConfigurationChannelTab($channelCode); + + $this->getElement('calculator_configuration_amount', ['%channelCode%' => $channelCode])->setValue((string) $amount); + } + + public function chooseCalculator(string $calculatorName): void + { + $this->getElement('calculator')->selectOption($calculatorName); + $this->waitForFormUpdate(); + } + + public function addRule(string $type): void + { + $this->getElement('add_rule_button', ['%type%' => $type])->press(); + $this->waitForFormUpdate(); + } + + public function fillLastRuleOption(string $fieldName, string $value): void + { + $lastRule = $this->getElement('last_rule'); + + $lastRule->fillField($fieldName, $value); + } + + public function fillLastRuleOptionForChannel(string $channelCode, string $fieldName, string $value): void + { + $lastRule = $this->getElement('last_rule'); + + TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode); + + $lastRule->find('css', sprintf('[id$="_configuration_%s"]', $channelCode))->fillField($fieldName, $value); + } + + public function getShippingChargesValidationErrorsCount(string $channelCode): int + { + return count( + $this + ->getElement('calculator_configuration_channel_tab_content', ['%channelCode%' => $channelCode]) + ->findAll('css', '.invalid-feedback'), + ); + } + + public function setField(string $field, string $value): void + { + $this->getDocument()->fillField($field, $value); + } + + /** + * @return array + */ + protected function getDefinedElements(): array + { + return [ + 'add_rule_button' => '[data-test-rules] [data-test-add-%type%]', + 'calculator' => '#sylius_shipping_method_calculator', + 'calculator_configuration_amount' => '#sylius_shipping_method_configuration_%channelCode%_amount', + 'calculator_configuration_channel_tab' => '[data-test-calculator-configuration] [data-test-channel-tab="%channelCode%"]', + 'calculator_configuration_channel_tab_content' => '[data-test-calculator-configuration] [data-test-channel-tab-content="%channelCode%"]', + 'channel' => '[name="sylius_shipping_method[channels][]"][value="%channelCode%"]', + 'code' => '#sylius_shipping_method_code', + 'description' => '#sylius_shipping_method_translations_%localeCode%_description', + 'enabled' => '#sylius_shipping_method_enabled', + 'form' => '[data-live-name-value="sylius_admin:shipping_method:form"]', + 'last_rule' => '[data-test-rules] [data-test-entry-row]:last-child', + 'last_rule_amount' => '[data-test-rules] [data-test-entry-row]:last-child [id$="_configuration_%channelCode%_amount"]', + 'last_rule_weight' => '[data-test-rules] [data-test-entry-row]:last-child [id$="_configuration_weight"]', + 'name' => '#sylius_shipping_method_translations_%localeCode%_name', + 'position' => '#sylius_shipping_method_position', + 'zone' => '#sylius_shipping_method_zone', + ]; + } + + private function selectCalculatorConfigurationChannelTab(string $channelCode): void + { + if (!DriverHelper::isJavascript($this->getDriver())) { + throw new \RuntimeException('This method can be used only with JavaScript enabled'); + } + + $this->getElement('calculator_configuration_channel_tab', ['%channelCode%' => $channelCode])->click(); + } +} diff --git a/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElementInterface.php new file mode 100644 index 0000000000..50eccb91ee --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/ShippingMethod/FormElementInterface.php @@ -0,0 +1,63 @@ +getElement('code')->getValue(); + } + + public function nameIt(string $name, string $localeCode): void + { + $this->getElement('name', ['%locale_code%' => $localeCode])->setValue($name); + } + + public function slugIt(string $slug, string $localeCode): void + { + $this->getElement('slug', ['%locale_code%' => $localeCode])->setValue($slug); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'code' => '[data-test-code]', + 'form' => '[data-live-name-value="sylius_admin:taxon:form"]', + 'name' => '[name="taxon[translations][%locale_code%][name]"]', + 'slug' => '[name="taxon[translations][%locale_code%][slug]"]', + ]); + } +} diff --git a/src/Sylius/Behat/Element/Admin/Taxon/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Taxon/FormElementInterface.php new file mode 100644 index 0000000000..f65fd9f766 --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/Taxon/FormElementInterface.php @@ -0,0 +1,25 @@ +getElement('add_image')->press(); + $this->waitForFormUpdate(); + + $lastImage = $this->getElement('last_image'); + + if (null !== $type) { + $lastImage->fillField('Type', $type); + } + + $filesPath = $this->getParameter('files_path'); + $lastImage->find('css', '[data-test-file]')->attachFile($filesPath . $path); + } + + public function changeImageWithType(string $type, string $path): void + { + $image = $this->getElement('image_with_type', ['%type%' => $type]); + + $filesPath = $this->getParameter('files_path'); + $image->find('css', '[data-test-file]')->attachFile($filesPath . $path); + } + + public function modifyFirstImageType(string $type): void + { + $this->getElement('first_image')->fillField('Type', $type); + } + + public function removeImageWithType(string $type): void + { + $this->getElement('delete_image', ['%type%' => $type])->press(); + $this->waitForFormUpdate(); + } + + public function removeFirstImage(): void + { + $this->getElement('first_image')->find('css', '[data-test-delete-image]')->press(); + $this->waitForFormUpdate(); + } + + public function isImageWithTypeDisplayed(string $type): bool + { + try { + $image = $this->getElement('image_with_type', ['%type%' => $type]); + } catch (ElementNotFoundException) { + return false; + } + + $imageUrl = $image->getAttribute('data-test-image-url'); + $this->getDriver()->visit($imageUrl); + $statusCode = $this->getDriver()->getStatusCode(); + $this->getDriver()->back(); + + return in_array($statusCode, [200, 304], true); + } + + public function countImages(): int + { + return count($this->getElement('images')->findAll('css', '[data-test-image]')); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'add_image' => '[data-test-images] [data-test-add-image]', + 'delete_image' => '[data-test-images] [data-test-image][data-test-type="%type%"] [data-test-delete-image]', + 'first_image' => '[data-test-images] [data-test-image]:first-child', + 'form' => '[data-live-name-value="sylius_admin:taxon:form"]', + 'image_with_type' => '[data-test-images] [data-test-image][data-test-type="%type%"]', + 'images' => '[data-test-images]', + 'last_image' => '[data-test-images] [data-test-image]:last-child', + ]); + } +} diff --git a/src/Sylius/Behat/Element/Admin/Taxon/ImageFormElementInterface.php b/src/Sylius/Behat/Element/Admin/Taxon/ImageFormElementInterface.php new file mode 100644 index 0000000000..8047a3fa12 --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/Taxon/ImageFormElementInterface.php @@ -0,0 +1,33 @@ +getDocument()->find('css', 'i.ui.avatar.user.icon'); - - return $avatarElement !== null; + return $this->getAvatarImagePath() === ''; } private function getAvatarImagePath(): string { - $image = $this->getDocument()->find('css', 'img.ui.avatar.image'); + $userAvatar = $this->getElement('user_avatar'); - if (null === $image) { - return ''; - } + return $userAvatar->getAttribute('data-test-user-avatar'); + } - return $image->getAttribute('src'); + /** + * @return array + */ + protected function getDefinedElements(): array + { + return [ + 'user_avatar' => '[data-test-user-avatar]', + ]; } } diff --git a/src/Sylius/Behat/Element/Admin/Zone/FormElement.php b/src/Sylius/Behat/Element/Admin/Zone/FormElement.php new file mode 100644 index 0000000000..80d800190b --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/Zone/FormElement.php @@ -0,0 +1,125 @@ +getElement('name')->getValue(); + } + + public function getType(): string + { + return $this->getElement('type')->getValue(); + } + + public function isTypeFieldDisabled(): bool + { + return $this->getElement('type')->hasAttribute('disabled'); + } + + public function getScope(): string + { + return $this->getElement('scope')->getValue(); + } + + public function selectScope(string $scope): void + { + $this->getDocument()->selectFieldOption('Scope', $scope); + } + + public function hasMember(string $member): bool + { + return $this->hasElement('zone_member', ['%name%' => $member]); + } + + public function countMembers(): int + { + return count($this->getElement('zone_members')->findAll('css', '[data-test-zone-member]')); + } + + public function addMember(): void + { + $this->getElement('add_member')->click(); + $this->waitForElement(5, 'zone_member_added'); + } + + public function removeMember(string $member): void + { + $this->getElement('zone_member_delete', ['%name%' => $member])->click(); + $this->waitForElement(5, 'zone_member', ['%name%' => $member], false); + } + + public function chooseMember(string $name): void + { + $select = $this->getElement('zone_member_last')->find('css', 'select'); + if (null === $select) { + throw new ElementNotFoundException($this->getSession(), 'select', 'css', 'select'); + } + + $select->selectOption($name); + } + + public function getFormValidationMessage(): string + { + return $this->getElement('form_validation_message')->getText(); + } + + protected function getCodeElement(): NodeElement + { + return $this->getElement('code'); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'add_member' => '[data-test-add-member]', + 'code' => '[data-test-code]', + 'form' => 'form', + 'form_validation_message' => 'form > div.alert.alert-danger.d-block', + 'name' => '[data-test-name]', + 'scope' => '[data-test-scope]', + 'type' => '[data-test-type]', + 'zone_member' => '[data-test-zone-member]:contains("%name%")', + 'zone_member_added' => '[data-test-zone-member]:last-child option:not([selected="selected"])', + 'zone_member_delete' => '[data-test-zone-member]:contains("%name%") button[name$="[delete]"]', + 'zone_member_last' => '[data-test-members]:last-child', + 'zone_members' => '[data-test-members]', + ]); + } + + private function waitForElement( + int $timeout, + string $elementName, + array $parameters = [], + bool $shouldExist = true, + ): bool { + return $this->getDocument()->waitFor( + $timeout, + fn (): bool => $shouldExist && $this->hasElement($elementName, $parameters), + ); + } +} diff --git a/src/Sylius/Behat/Element/Admin/Zone/FormElementInterface.php b/src/Sylius/Behat/Element/Admin/Zone/FormElementInterface.php new file mode 100644 index 0000000000..2acde67b17 --- /dev/null +++ b/src/Sylius/Behat/Element/Admin/Zone/FormElementInterface.php @@ -0,0 +1,47 @@ +getChannelPriceRow($channelName); + $channelPriceRow = $this->getSimpleProductPricingRowForChannel($channelName); if (null === $channelPriceRow) { throw new \InvalidArgumentException(sprintf('Channel "%s" does not exist', $channelName)); @@ -84,8 +84,8 @@ final class PricingElement extends Element implements PricingElementInterface protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'simple_product_pricing_row' => '#pricing tr:contains("%channelName%")', - 'variant_pricing_row' => 'tr:contains("%variantName%") + tr:contains("%channelName%")', + 'simple_product_pricing_row' => '[data-test-simple-product="%channelName%"]', + 'variant_pricing_row' => '[data-test-variants="%channelName%.%variantName%"]', ]); } diff --git a/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php b/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php index ef7540695e..4d6ff61a7c 100644 --- a/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php +++ b/src/Sylius/Behat/Element/Product/ShowPage/VariantsElement.php @@ -74,19 +74,11 @@ final class VariantsElement extends Element implements VariantsElementInterface string $lowestPriceBeforeDiscount, string $channelName, ): bool { - /** @var NodeElement[] $variantRows */ - $variantRows = $this->getDocument()->findAll('css', '#variants .variants-accordion__title'); - /** @var NodeElement $variant */ - foreach ($variantRows as $variant) { - if ($this->isVariantWithLowestPriceBeforeDiscountInChannel( - $variant, - $productVariantName, - $lowestPriceBeforeDiscount, - $channelName, - )) { - return true; - } + $variant = $this->getDocument()->find('css', sprintf('[data-test-lowest-price-before-the-discount="%s.%s"]', $productVariantName, $channelName)); + + if ($variant) { + return $variant->getText() === $lowestPriceBeforeDiscount; } return false; @@ -117,46 +109,8 @@ final class VariantsElement extends Element implements VariantsElementInterface return false; } - private function isVariantWithLowestPriceBeforeDiscountInChannel( - NodeElement $variant, - string $name, - string $lowestPriceBeforeDiscount, - string $channel, - ): bool { - $variantContent = $variant->getParent()->find( - 'css', - sprintf('.variants-accordion__content.%s', $this->getItemIndexClass($variant)), - ); - - $headerRow = $variantContent->find('css', '.pricing-header'); - $lowestPriceColumnIndex = $this->getLowestPriceColumnIndex($headerRow); - - if ($lowestPriceColumnIndex === null) { - return false; - } - - return - $variant->find('css', '.content .variant-name')->getText() === $name && - $variantContent->find( - 'css', - sprintf('tr.pricing:contains("%s") td:nth-child(%s)', $channel, $lowestPriceColumnIndex), - )->getText() === $lowestPriceBeforeDiscount - ; - } - private function getItemIndexClass(NodeElement $variant): string { return explode(' ', $variant->getAttribute('class'))[1]; } - - private function getLowestPriceColumnIndex(NodeElement $headerRow): ?int - { - foreach ($headerRow->findAll('css', 'td') as $index => $cell) { - if ($cell->getText() === 'Lowest price before discount') { - return $index + 1; - } - } - - return null; - } } diff --git a/src/Sylius/Behat/NotificationType.php b/src/Sylius/Behat/NotificationType.php index 9a38a8b9ef..0400bd0508 100644 --- a/src/Sylius/Behat/NotificationType.php +++ b/src/Sylius/Behat/NotificationType.php @@ -26,11 +26,21 @@ final class NotificationType implements \Stringable return $this->value; } + /** + * @deprecated Use ::error() instead + * + * @todo remove and replace all usages with ::error() in 2.0 + */ public static function failure(): self { return static::getTyped('failure'); } + public static function error(): self + { + return static::getTyped('error'); + } + public static function success(): self { return static::getTyped('success'); diff --git a/src/Sylius/Behat/Page/Admin/Account/LoginPage.php b/src/Sylius/Behat/Page/Admin/Account/LoginPage.php index f59b337bfb..6fff88db8a 100644 --- a/src/Sylius/Behat/Page/Admin/Account/LoginPage.php +++ b/src/Sylius/Behat/Page/Admin/Account/LoginPage.php @@ -45,7 +45,7 @@ class LoginPage extends SymfonyPage implements LoginPageInterface protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'validation_error' => '.message.negative', + 'validation_error' => '[data-test-invalid-credentials-message]', ]); } } diff --git a/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php b/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php index 14879e0b8a..1e051e29c6 100644 --- a/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/Administrator/CreatePage.php @@ -17,66 +17,10 @@ use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; class CreatePage extends BaseCreatePage implements CreatePageInterface { - public function isAvatarAttached(): bool - { - return $this->getElement('add_avatar')->has('css', 'img'); - } - - public function attachAvatar(string $path): void - { - $filesPath = $this->getParameter('files_path'); - - $imageForm = $this->getElement('add_avatar')->find('css', 'input[type="file"]'); - - $imageForm->attachFile($filesPath . $path); - } - - public function enable(): void - { - $this->getElement('enabled')->check(); - } - - public function specifyUsername(string $username): void - { - $this->getElement('name')->setValue($username); - } - - public function specifyEmail(string $email): void - { - $this->getElement('email')->setValue($email); - } - - public function specifyFirstName(string $firstName): void - { - $this->getElement('first_name')->setValue($firstName); - } - - public function specifyLastName(string $lastName): void - { - $this->getElement('last_name')->setValue($lastName); - } - - public function specifyPassword(string $password): void - { - $this->getElement('password')->setValue($password); - } - - public function specifyLocale(string $localeCode): void - { - $this->getElement('locale_code')->selectOption($localeCode); - } + use FormAwareTrait; protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'add_avatar' => '#add-avatar', - 'email' => '#sylius_admin_user_email', - 'enabled' => '#sylius_admin_user_enabled', - 'first_name' => '#sylius_admin_user_firstName', - 'last_name' => '#sylius_admin_user_lastName', - 'locale_code' => '#sylius_admin_user_localeCode', - 'name' => '#sylius_admin_user_username', - 'password' => '#sylius_admin_user_plainPassword', - ]); + return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements()); } } diff --git a/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php index e2f6f22510..4a16ea059b 100644 --- a/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Administrator/CreatePageInterface.php @@ -15,23 +15,6 @@ namespace Sylius\Behat\Page\Admin\Administrator; use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; -interface CreatePageInterface extends BaseCreatePageInterface +interface CreatePageInterface extends BaseCreatePageInterface, FormAwareInterface { - public function isAvatarAttached(): bool; - - public function attachAvatar(string $path): void; - - public function enable(): void; - - public function specifyUsername(string $username): void; - - public function specifyEmail(string $email): void; - - public function specifyFirstName(string $firstName): void; - - public function specifyLastName(string $lastName): void; - - public function specifyPassword(string $password): void; - - public function specifyLocale(string $localeCode): void; } diff --git a/src/Sylius/Behat/Page/Admin/Administrator/FormAwareInterface.php b/src/Sylius/Behat/Page/Admin/Administrator/FormAwareInterface.php new file mode 100644 index 0000000000..c589f0333f --- /dev/null +++ b/src/Sylius/Behat/Page/Admin/Administrator/FormAwareInterface.php @@ -0,0 +1,51 @@ +getElement('field_first_name')->setValue($firstName); + } + + public function getFirstName(): string + { + return $this->getElement('field_first_name')->getValue(); + } + + public function setLastName(string $lastName): void + { + $this->getElement('field_last_name')->setValue($lastName); + } + + public function getLastName(): string + { + return $this->getElement('field_last_name')->getValue(); + } + + public function setUsername(string $username): void + { + $this->getElement('field_username')->setValue($username); + } + + public function getUsername(): string + { + return $this->getElement('field_username')->getValue(); + } + + public function setEmail(string $email): void + { + $this->getElement('field_email')->setValue($email); + } + + public function getEmail(): string + { + return $this->getElement('field_email')->getValue(); + } + + public function setPassword(string $password): void + { + $this->getElement('field_password')->setValue($password); + } + + public function getPassword(): string + { + return $this->getElement('field_password')->getValue(); + } + + public function setLocale(string $locale): void + { + $this->getElement('field_locale_code')->setValue($locale); + } + + public function getLocale(): string + { + return $this->getElement('field_locale_code')->getValue(); + } + + public function enable(): void + { + $this->getElement('field_enabled')->check(); + } + + public function disable(): void + { + $this->getElement('field_enabled')->uncheck(); + } + + public function isEnabled(): bool + { + return $this->getElement('field_enabled')->getValue(); + } + + public function isAvatarAttached(): bool + { + return $this->getElement('avatar_image')->getAttribute('data-test-avatar-image') !== ''; + } + + public function attachAvatar(string $path): void + { + $filesPath = $this->getParameter('files_path'); + $avatarField = $this->getElement('field_avatar'); + $avatarField->attachFile($filesPath . $path); + } + + /** + * @return array + */ + protected function getDefinedFormElements(): array + { + return [ + 'avatar_image' => '[data-test-avatar-image]', + 'field_avatar' => '#sylius_admin_user_avatar_file', + 'field_email' => '#sylius_admin_user_email', + 'field_enabled' => '#sylius_admin_user_enabled', + 'field_first_name' => '#sylius_admin_user_firstName', + 'field_last_name' => '#sylius_admin_user_lastName', + 'field_locale_code' => '#sylius_admin_user_localeCode', + 'field_name' => '#sylius_admin_user_username', + 'field_password' => '#sylius_admin_user_plainPassword', + 'field_username' => '#sylius_admin_user_username', + ]; + } +} diff --git a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php index 236452ba51..b3963dcba2 100644 --- a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePage.php @@ -17,38 +17,11 @@ use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage; class UpdatePage extends BaseUpdatePage implements UpdatePageInterface { - public function attachAvatar(string $path): void - { - $filesPath = $this->getParameter('files_path'); - - $imageForm = $this->getElement('add_avatar')->find('css', 'input[type="file"]'); - - $imageForm->attachFile($filesPath . $path); - } - - public function changeUsername(string $username): void - { - $this->getElement('username')->setValue($username); - } - - public function changeEmail(string $email): void - { - $this->getElement('email')->setValue($email); - } - - public function changePassword(string $password): void - { - $this->getElement('password')->setValue($password); - } - - public function changeLocale(string $localeCode): void - { - $this->getElement('locale_code')->selectOption($localeCode); - } + use FormAwareTrait; public function removeAvatar(): void { - $this->getElement('remove_avatar')->click(); + $this->getElement('button_delete_avatar')->click(); } public function hasAvatar(string $avatarPath): bool @@ -58,27 +31,28 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return str_contains($srcPath, $avatarPath); } + public function changeLocale(string $localeCode): void + { + $this->getElement('locale-switch')->selectOption($localeCode); + } + protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'add_avatar' => '#add-avatar', - 'email' => '#sylius_admin_user_email', - 'enabled' => '#sylius_admin_user_enabled', - 'locale_code' => '#sylius_admin_user_localeCode', - 'password' => '#sylius_admin_user_plainPassword', - 'remove_avatar' => '.ui.icon.red.labeled.button', - 'username' => '#sylius_admin_user_username', + return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements(), [ + 'button_delete_avatar' => '[data-test-delete-avatar-button]', + 'locale-switch' => '[data-test-admin-locale-switch]', ]); } private function getAvatarImagePath(): string { - $image = $this->getElement('add_avatar')->find('css', 'img'); + $avatarImage = $this->getElement('avatar_image'); + $imagePath = $avatarImage->getAttribute('data-test-avatar-image'); - if (null === $image) { + if (null === $imagePath) { return ''; } - return $image->getAttribute('src'); + return $imagePath; } } diff --git a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php index 26854bd946..57bc9fff06 100644 --- a/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Administrator/UpdatePageInterface.php @@ -15,19 +15,11 @@ namespace Sylius\Behat\Page\Admin\Administrator; use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface; -interface UpdatePageInterface extends BaseUpdatePageInterface +interface UpdatePageInterface extends BaseUpdatePageInterface, FormAwareInterface { - public function attachAvatar(string $path): void; - - public function changeUsername(string $username): void; - - public function changeEmail(string $email): void; - - public function changePassword(string $password): void; - - public function changeLocale(string $localeCode): void; - public function removeAvatar(): void; public function hasAvatar(string $avatarPath): bool; + + public function changeLocale(string $localeCode): void; } diff --git a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php index 773d109540..8755f105c3 100644 --- a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePage.php @@ -20,24 +20,11 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface { use SpecifiesItsField; - public function checkIfScopeConfigurationFormIsVisible(): bool - { - return $this->hasElement('products'); - } - - public function checkIfActionConfigurationFormIsVisible(): bool - { - return $this->hasElement('amount'); - } - protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'amount' => '[name^="sylius_catalog_promotion[actions][0][configuration]"][name$="[amount]"]', 'code' => '#sylius_catalog_promotion_code', - 'endDate' => '#sylius_catalog_promotion_endDate', 'name' => '#sylius_catalog_promotion_name', - 'products' => '[name="sylius_catalog_promotion[scopes][0][configuration][products]"]', ]); } } diff --git a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php index ed8267f63e..67adf6cf7d 100644 --- a/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/CatalogPromotion/CreatePageInterface.php @@ -17,9 +17,5 @@ use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; interface CreatePageInterface extends BaseCreatePageInterface { - public function checkIfScopeConfigurationFormIsVisible(): bool; - - public function checkIfActionConfigurationFormIsVisible(): bool; - public function specifyCode(string $code): void; } diff --git a/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php b/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php index 1b0c205c74..9333e04b94 100644 --- a/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php +++ b/src/Sylius/Behat/Page/Admin/CatalogPromotion/ShowPage.php @@ -47,7 +47,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasActionWithPercentageDiscount(string $amount): bool { - $amountsElements = $this->getDocument()->findAll('css', '[data-test-action-amount]'); + $amountsElements = $this->getElement('actions')->findAll('css', '[data-test-action] [data-test-amount]'); foreach ($amountsElements as $amountElement) { if ($amountElement->getText() === $amount) { return true; @@ -59,7 +59,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasActionWithFixedDiscount(string $amount, ChannelInterface $channel): bool { - $amountsElements = $this->getDocument()->findAll('css', '[data-test-action-' . $channel->getCode() . '-amount]'); + $amountsElements = $this->getElement('actions')->findAll('css', '[data-test-' . $channel->getCode() . '-amount]'); foreach ($amountsElements as $amountElement) { if ($amountElement->getText() === $amount) { return true; @@ -71,7 +71,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasScopeWithVariant(ProductVariantInterface $variant): bool { - $variantsElements = $this->getDocument()->findAll('css', '[data-test-scope-variants]'); + $variantsElements = $this->getElement('scopes')->findAll('css', '[data-test-variants] li'); foreach ($variantsElements as $variantElement) { if ($variantElement->getText() === $variant->getCode()) { return true; @@ -83,7 +83,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasScopeWithProduct(ProductInterface $product): bool { - $productsElements = $this->getDocument()->findAll('css', '[data-test-scope-products]'); + $productsElements = $this->getElement('scopes')->findAll('css', '[data-test-products] li'); foreach ($productsElements as $productElement) { if ($productElement->getText() === $product->getCode()) { return true; @@ -95,16 +95,18 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function isExclusive(): bool { - return $this->hasElement('exclusive'); + return null !== $this->getElement('exclusive')->find('css', 'svg.text-green'); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ + 'actions' => '[data-test-actions]', 'end_date' => '[data-test-end-date]', 'exclusive' => '[data-test-exclusive]', 'name' => '[data-test-name]', 'priority' => '[data-test-priority]', + 'scopes' => '[data-test-scopes]', 'start_date' => '[data-test-start-date]', ]); } diff --git a/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php b/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php index 833ea30f23..739c065f72 100644 --- a/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/Channel/CreatePage.php @@ -14,12 +14,14 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Channel; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; use Sylius\Behat\Behaviour\DescribesIt; use Sylius\Behat\Behaviour\NamesIt; use Sylius\Behat\Behaviour\SpecifiesItsField; use Sylius\Behat\Behaviour\Toggles; use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; -use Sylius\Behat\Service\AutocompleteHelper; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; +use Symfony\Component\Routing\RouterInterface; class CreatePage extends BaseCreatePage implements CreatePageInterface { @@ -27,67 +29,21 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface use SpecifiesItsField; use DescribesIt; use Toggles; + use FormTrait; - public function setHostname(string $hostname): void - { - $this->getElement('hostname')->setValue($hostname); + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + string $routeName, + private AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $routeName); } - public function setContactEmail(string $contactEmail): void + protected function getToggleableElement(): NodeElement { - $this->getElement('contact_email')->setValue($contactEmail); - } - - public function setContactPhoneNumber(string $contactPhoneNumber): void - { - $this->getElement('contact_phone_number')->setValue($contactPhoneNumber); - } - - public function defineColor(string $color): void - { - $this->getElement('color')->setValue($color); - } - - public function chooseCurrency(string $currencyCode): void - { - $this->getDocument()->selectFieldOption('Currencies', $currencyCode); - } - - public function chooseLocale(string $language): void - { - $this->getDocument()->selectFieldOption('Locales', $language); - } - - public function chooseDefaultTaxZone(string $taxZone): void - { - $this->getDocument()->selectFieldOption('Default tax zone', $taxZone); - } - - public function chooseDefaultLocale(?string $locale): void - { - if (null !== $locale) { - $this->getElement('default_locale')->selectOption($locale); - } - } - - public function chooseOperatingCountries(array $countries): void - { - foreach ($countries as $country) { - $this->getElement('countries')->selectOption($country, true); - } - } - - public function chooseBaseCurrency(?string $currency): void - { - if (null !== $currency) { - $this->getElement('currencies')->selectOption($currency); - $this->getElement('base_currency')->selectOption($currency); - } - } - - public function chooseTaxCalculationStrategy(string $taxZone): void - { - $this->getDocument()->selectFieldOption('Tax calculation strategy', $taxZone); + return $this->getElement('enabled'); } public function allowToSkipShippingStep(): void @@ -100,34 +56,11 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface $this->getDocument()->checkField('Skip payment step if only one payment method is available?'); } - public function specifyMenuTaxon(string $menuTaxon): void - { - $menuTaxonElement = $this->getElement('menu_taxon')->getParent(); - - AutocompleteHelper::chooseValue($this->getSession(), $menuTaxonElement, $menuTaxon); - } - - protected function getToggleableElement(): NodeElement - { - return $this->getElement('enabled'); - } - protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'base_currency' => '#sylius_channel_baseCurrency', - 'code' => '#sylius_channel_code', - 'color' => '#sylius_channel_color', - 'contact_email' => '#sylius_channel_contactEmail', - 'contact_phone_number' => '#sylius_channel_contactPhoneNumber', - 'countries' => '#sylius_channel_countries', - 'currencies' => '#sylius_channel_currencies', - 'default_locale' => '#sylius_channel_defaultLocale', - 'enabled' => '#sylius_channel_enabled', - 'hostname' => '#sylius_channel_hostname', - 'locales' => '#sylius_channel_locales', - 'menu_taxon' => '#sylius_channel_menuTaxon', - 'name' => '#sylius_channel_name', - ]); + return array_merge( + parent::getDefinedElements(), + $this->getDefinedFormElements(), + ); } } diff --git a/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php index 2789ef3161..513259a917 100644 --- a/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Channel/CreatePageInterface.php @@ -37,16 +37,16 @@ interface CreatePageInterface extends BaseCreatePageInterface public function chooseLocale(string $language): void; - public function chooseCurrency(string $currencyCode): void; + public function chooseCurrency(string $currencyName): void; public function chooseDefaultTaxZone(string $taxZone): void; - public function chooseDefaultLocale(?string $locale): void; + public function chooseDefaultLocale(string $locale): void; /** @param string[] $countries */ public function chooseOperatingCountries(array $countries): void; - public function chooseBaseCurrency(?string $currency): void; + public function chooseBaseCurrency(string $currency): void; public function chooseTaxCalculationStrategy(string $taxCalculationStrategy): void; diff --git a/src/Sylius/Behat/Page/Admin/Channel/FormTrait.php b/src/Sylius/Behat/Page/Admin/Channel/FormTrait.php new file mode 100644 index 0000000000..138201da88 --- /dev/null +++ b/src/Sylius/Behat/Page/Admin/Channel/FormTrait.php @@ -0,0 +1,147 @@ + '[data-test-base-currency]', + 'code' => '[data-test-code]', + 'color' => '[data-test-color]', + 'contact_email' => '[data-test-contact-email]', + 'contact_phone_number' => '[data-test-contact-phone-number]', + 'countries' => '#sylius_channel_countries', + 'currencies' => '#sylius_channel_currencies', + 'default_locale' => '#sylius_channel_defaultLocale', + 'default_tax_zone' => '[data-test-default-tax-zone]', + 'discounted_products_checking_period' => '[data-test-lowest-price-for-discounted-products-checking-period]', + 'enabled' => '[data-test-enabled]', + 'form' => 'form', + 'hostname' => '[data-test-hostname]', + 'locales' => '[data-test-locales]', + 'menu_taxon' => '[data-test-menu-taxon]', + 'name' => '[data-test-name]', + 'tax_calculation_strategy' => '[data-test-tax-calculation-strategy]', + 'theme' => '[data-test-theme]', + ]; + } + + public function setHostname(string $hostname): void + { + $this->getElement('hostname')->setValue($hostname); + } + + public function setTheme(string $themeName): void + { + $this->getElement('theme')->selectOption($themeName); + } + + public function getTheme(): string + { + return $this->getElement('theme')->getValue(); + } + + public function setContactEmail(string $contactEmail): void + { + $this->getElement('contact_email')->setValue($contactEmail); + } + + public function setContactPhoneNumber(string $contactPhoneNumber): void + { + $this->getElement('contact_phone_number')->setValue($contactPhoneNumber); + } + + public function defineColor(string $color): void + { + $this->getElement('color')->setValue($color); + } + + public function chooseCurrency(string $currencyName): void + { + $this->getElement('currencies')->selectOption($currencyName, true); + } + + public function chooseLocale(string $language): void + { + $this->getElement('locales')->selectOption($language); + } + + public function chooseDefaultTaxZone(string $taxZone): void + { + $this->getElement('default_tax_zone')->selectOption($taxZone); + } + + public function chooseDefaultLocale(string $locale): void + { + $this->getElement('default_locale')->selectOption($locale); + } + + public function chooseOperatingCountries(array $countries): void + { + foreach ($countries as $country) { + $this->getElement('countries')->selectOption($country, true); + } + } + + public function chooseBaseCurrency(string $currency): void + { + $this->getElement('currencies')->selectOption($currency, true); + $this->getElement('base_currency')->selectOption($currency); + } + + public function getMenuTaxon(): string + { + return $this->getSelectedOptionText('menu_taxon'); + } + + public function specifyMenuTaxon(string $menuTaxon): void + { + $this->autocompleteHelper->selectByName( + $this->getDriver(), + $this->getElement('menu_taxon')->getXpath(), + $menuTaxon, + ); + $this->waitForFormUpdate(); + } + + public function getTaxCalculationStrategy(): string + { + return $this->getSelectedOptionText('tax_calculation_strategy'); + } + + public function chooseTaxCalculationStrategy(string $taxCalculationStrategy): void + { + $this->getElement('tax_calculation_strategy')->selectOption($taxCalculationStrategy); + } + + private function getSelectedOptionText(string $element): string + { + return $this + ->getElement($element) + ->find('css', 'option:selected') + ->getText() + ; + } + + private function waitForFormUpdate(): void + { + $form = $this->getElement('form'); + sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute + $form->waitFor(1500, function () use ($form) { + return !$form->hasAttribute('busy'); + }); + } +} diff --git a/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php index 6df7d5959a..461fd38a57 100644 --- a/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Channel/UpdatePage.php @@ -14,74 +14,48 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Channel; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; use Sylius\Behat\Behaviour\ChecksCodeImmutability; use Sylius\Behat\Behaviour\Toggles; use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage; -use Sylius\Behat\Service\AutocompleteHelper; -use Sylius\Behat\Service\DriverHelper; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; +use Symfony\Component\Routing\RouterInterface; class UpdatePage extends BaseUpdatePage implements UpdatePageInterface { use ChecksCodeImmutability; use Toggles; + use FormTrait; - public function setTheme(string $themeName): void - { - $this->getDocument()->selectFieldOption('Theme', $themeName); + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + string $routeName, + private AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $routeName); } - public function unsetTheme(): void + public function getLocales(): array { - $this->getDocument()->selectFieldOption('Theme', ''); + return array_map( + fn (NodeElement $element) => $element->getText(), + $this->getElement('locales')->findAll('css', 'option:selected'), + ); } - public function chooseLocale(string $language): void + public function getCurrencies(): array { - $this->getDocument()->selectFieldOption('Locales', $language); + return array_map( + fn (NodeElement $element) => $element->getText(), + $this->getElement('currencies')->findAll('css', 'option:selected'), + ); } - public function chooseCurrency(string $currencyCode): void + public function getDefaultTaxZone(): ?string { - $this->getDocument()->selectFieldOption('Currencies', $currencyCode); - } - - public function chooseDefaultTaxZone(string $taxZone): void - { - $this->getDocument()->selectFieldOption('Default tax zone', $taxZone); - } - - public function chooseTaxCalculationStrategy(string $taxZone): void - { - $this->getDocument()->selectFieldOption('Tax calculation strategy', $taxZone); - } - - public function isLocaleChosen(string $language): bool - { - return $this->getElement('locales')->find('named', ['option', $language])->hasAttribute('selected'); - } - - public function isCurrencyChosen(string $currencyCode): bool - { - return $this->getElement('currencies')->find('named', ['option', $currencyCode])->hasAttribute('selected'); - } - - public function isDefaultTaxZoneChosen(string $taxZone): bool - { - return $this->getElement('default_tax_zone')->find('named', ['option', $taxZone])->hasAttribute('selected'); - } - - public function isAnyDefaultTaxZoneChosen(): bool - { - return null !== $this->getElement('default_tax_zone')->find('css', '[selected]'); - } - - public function isTaxCalculationStrategyChosen(string $taxCalculationStrategy): bool - { - return $this - ->getElement('tax_calculation_strategy') - ->find('named', ['option', $taxCalculationStrategy]) - ->hasAttribute('selected') - ; + return $this->getElement('default_tax_zone')->find('css', 'option:selected')?->getText(); } public function isBaseCurrencyDisabled(): bool @@ -89,31 +63,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return $this->getElement('base_currency')->hasAttribute('disabled'); } - public function changeMenuTaxon(string $menuTaxon): void - { - $menuTaxonElement = $this->getElement('menu_taxon')->getParent(); - - AutocompleteHelper::chooseValue($this->getSession(), $menuTaxonElement, $menuTaxon); - } - - public function getMenuTaxon(): string - { - $element = $this->getElement('menu_taxon'); - - if (DriverHelper::isJavascript($this->getDriver())) { - $this->getDocument()->waitFor(1, function () use ($element) { - return $element->getText() !== ''; - }); - } - - return $element->getText(); - } - - public function getUsedTheme(): string - { - return $this->getElement('theme')->getValue(); - } - protected function getCodeElement(): NodeElement { return $this->getElement('code'); @@ -126,18 +75,9 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'base_currency' => '#sylius_channel_baseCurrency', - 'code' => '#sylius_channel_code', - 'currencies' => '#sylius_channel_currencies', - 'default_locale' => '#sylius_channel_defaultLocale', - 'default_tax_zone' => '#sylius_channel_defaultTaxZone', - 'discounted_products_checking_period' => '#sylius_channel_channelPriceHistoryConfig_lowestPriceForDiscountedProductsCheckingPeriod', - 'enabled' => '#sylius_channel_enabled', - 'locales' => '#sylius_channel_locales', - 'menu_taxon' => '#sylius_channel_menuTaxon ~ .text', - 'name' => '#sylius_channel_name', - 'tax_calculation_strategy' => '#sylius_channel_taxCalculationStrategy', - ]); + return array_merge( + parent::getDefinedElements(), + $this->getDefinedFormElements(), + ); } } diff --git a/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php index 235817c5be..8488d5927e 100644 --- a/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Channel/UpdatePageInterface.php @@ -13,7 +13,6 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Channel; -use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface; interface UpdatePageInterface extends BaseUpdatePageInterface @@ -22,38 +21,33 @@ interface UpdatePageInterface extends BaseUpdatePageInterface public function disable(): void; + public function getTheme(): string; + public function setTheme(string $themeName): void; - /** - * @throws ElementNotFoundException - */ - public function unsetTheme(): void; + /** @return string[] */ + public function getLocales(): array; public function chooseLocale(string $language): void; + /** @return string[] */ + public function getCurrencies(): array; + public function chooseCurrency(string $currencyCode): void; + public function getDefaultTaxZone(): ?string; + public function chooseDefaultTaxZone(string $taxZone): void; + public function getTaxCalculationStrategy(): string; + public function chooseTaxCalculationStrategy(string $taxCalculationStrategy): void; public function isCodeDisabled(): bool; - public function isLocaleChosen(string $language): bool; - - public function isCurrencyChosen(string $currencyCode): bool; - - public function isDefaultTaxZoneChosen(string $taxZone): bool; - - public function isAnyDefaultTaxZoneChosen(): bool; - - public function isTaxCalculationStrategyChosen(string $taxCalculationStrategy): bool; - public function isBaseCurrencyDisabled(): bool; - public function changeMenuTaxon(string $menuTaxon): void; + public function specifyMenuTaxon(string $menuTaxon): void; public function getMenuTaxon(): string; - - public function getUsedTheme(): string; } diff --git a/src/Sylius/Behat/Page/Admin/Country/CreatePage.php b/src/Sylius/Behat/Page/Admin/Country/CreatePage.php index d6a85658ea..db60509dfd 100644 --- a/src/Sylius/Behat/Page/Admin/Country/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/Country/CreatePage.php @@ -13,43 +13,58 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Country; -use Behat\Mink\Element\NodeElement; -use Sylius\Behat\Behaviour\ChoosesName; use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; use Webmozart\Assert\Assert; class CreatePage extends BaseCreatePage implements CreatePageInterface { - use ChoosesName; - - public function addProvince(string $name, string $code, ?string $abbreviation = null): void + public function selectCountry(string $countryName): void { - $this->getDocument()->clickLink('Add province'); + $this->getElement('code')->selectOption($countryName); + } - $provinceForm = $this->getLastProvinceElement(); + public function addProvince(): void + { + $count = count($this->getProvinceItems()); - $provinceForm->fillField('Name', $name); - $provinceForm->fillField('Code', $code); + $this->getElement('add_province')->click(); - if (null !== $abbreviation) { - $provinceForm->fillField('Abbreviation', $abbreviation); - } + $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getProvinceItems())); + } + + public function specifyProvinceName(string $name): void + { + $province = $this->getElement('last_province'); + $province->find('css', '[data-test-province-name]')->setValue($name); + } + + public function specifyProvinceCode(string $code): void + { + $province = $this->getElement('last_province'); + $province->find('css', '[data-test-province-code]')->setValue($code); + } + + public function specifyProvinceAbbreviation(string $abbreviation): void + { + $province = $this->getElement('last_province'); + $province->find('css', '[data-test-province-abbreviation]')->setValue($abbreviation); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'provinces' => '#sylius_country_provinces', + 'code' => '[data-test-code]', + 'provinces' => '[data-test-provinces]', + 'last_province' => '[data-test-provinces] [data-test-province]:last-child', + 'add_province' => '[data-test-add-province]', ]); } - private function getLastProvinceElement(): NodeElement + private function getProvinceItems(): array { - $provinces = $this->getElement('provinces'); - $items = $provinces->findAll('css', 'div[data-form-collection="item"]'); + $items = $this->getElement('provinces')->findAll('css', '[data-test-province]'); + Assert::isArray($items); - Assert::notEmpty($items); - - return end($items); + return $items; } } diff --git a/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php index e1017850c2..45ba678c94 100644 --- a/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Country/CreatePageInterface.php @@ -17,7 +17,13 @@ use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; interface CreatePageInterface extends BaseCreatePageInterface { - public function chooseName(string $name): void; + public function selectCountry(string $countryName): void; - public function addProvince(string $name, string $code, ?string $abbreviation = null): void; + public function addProvince(): void; + + public function specifyProvinceName(string $name): void; + + public function specifyProvinceCode(string $code): void; + + public function specifyProvinceAbbreviation(string $abbreviation): void; } diff --git a/src/Sylius/Behat/Page/Admin/Country/IndexPage.php b/src/Sylius/Behat/Page/Admin/Country/IndexPage.php index dc07e2458f..6d2374305f 100644 --- a/src/Sylius/Behat/Page/Admin/Country/IndexPage.php +++ b/src/Sylius/Behat/Page/Admin/Country/IndexPage.php @@ -20,12 +20,12 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface { public function isCountryDisabled(CountryInterface $country): bool { - return $this->checkCountryStatus($country, 'Disabled'); + return $this->checkCountryStatus($country, 'disabled'); } public function isCountryEnabled(CountryInterface $country): bool { - return $this->checkCountryStatus($country, 'Enabled'); + return $this->checkCountryStatus($country, 'enabled'); } private function checkCountryStatus(CountryInterface $country, string $status): bool @@ -36,6 +36,6 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface $row = $tableAccessor->getRowWithFields($table, ['code' => $country->getCode()]); $enabledField = $tableAccessor->getFieldFromRow($table, $row, 'enabled'); - return $enabledField->getText() === $status; + return $enabledField->has('css', sprintf('[data-test-status-%s]', $status)); } } diff --git a/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php index b873b99af1..840030c3c8 100644 --- a/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Country/UpdatePage.php @@ -30,6 +30,33 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return $codeField->getAttribute('disabled') === 'disabled'; } + public function addProvince(): void + { + $count = count($this->getProvinceItems()); + + $this->getElement('add_province')->click(); + + $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getProvinceItems())); + } + + public function specifyProvinceName(string $name): void + { + $province = $this->getElement('last_province'); + $province->find('css', '[data-test-province-name]')->setValue($name); + } + + public function specifyProvinceCode(string $code): void + { + $province = $this->getElement('last_province'); + $province->find('css', '[data-test-province-code]')->setValue($code); + } + + public function specifyProvinceAbbreviation(string $abbreviation): void + { + $province = $this->getElement('last_province'); + $province->find('css', '[data-test-province-abbreviation]')->setValue($abbreviation); + } + public function isThereProvince(string $provinceName): bool { $provinces = $this->getElement('provinces'); @@ -47,78 +74,35 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface public function removeProvince(string $provinceName): void { if ($this->isThereProvince($provinceName)) { - $provinces = $this->getElement('provinces'); + $province = $this->getProvinceElement($provinceName); - $item = $provinces - ->find('css', sprintf('div[data-form-collection="item"] input[value="%s"]', $provinceName)) - ->getParent() - ->getParent() - ->getParent() - ->getParent() - ->getParent() - ; - - $item->clickLink('Delete'); + $province->find('css', '[data-test-delete-province]')->click(); + $this->getDocument()->waitFor(5, fn () => !$this->isThereProvince($provinceName)); } } - public function addProvince(string $name, string $code, ?string $abbreviation = null): void - { - $this->clickAddProvinceButton(); - - $provinceForm = $this->getLastProvinceElement(); - - $provinceForm->fillField('Name', $name); - $provinceForm->fillField('Code', $code); - - if (null !== $abbreviation) { - $provinceForm->fillField('Abbreviation', $abbreviation); - } - } - - public function clickAddProvinceButton(): void - { - $this->getDocument()->clickLink('Add province'); - } - - public function nameProvince(string $name): void - { - $provinceForm = $this->getLastProvinceElement(); - - $provinceForm->fillField('Name', $name); - } - public function removeProvinceName(string $provinceName): void { if ($this->isThereProvince($provinceName)) { - $provinces = $this->getElement('provinces'); - - $item = $provinces->find('css', 'div[data-form-collection="item"] input[value="' . $provinceName . '"]')->getParent(); - $item->fillField('Name', ''); + $province = $this->getProvinceElement($provinceName); + $province->find('css', '[data-test-province-name]')->setValue(''); } } - public function specifyProvinceCode(string $code): void - { - $provinceForm = $this->getLastProvinceElement(); - - $provinceForm->fillField('Code', $code); - } - public function getFormValidationErrors(): array { - $errors = $this->getElement('form')->findAll('css', '.sylius-validation-error:not(.pointing)'); + $errors = $this->getElement('form')->findAll('css', '.alert-danger'); return array_map(fn (NodeElement $element) => $element->getText(), $errors); } public function getValidationMessage(string $element): string { - $provinceForm = $this->getLastProvinceElement(); + $province = $this->getElement('last_province'); - $foundElement = $provinceForm->find('css', '.sylius-validation-error'); + $foundElement = $province->find('css', '.invalid-feedback'); if (null === $foundElement) { - throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.invalid-feedback'); } return $foundElement->getText(); @@ -132,20 +116,25 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'code' => '#sylius_country_code', - 'enabled' => '#sylius_country_enabled', + 'code' => '[data-test-code]', + 'enabled' => '[data-test-enabled]', + 'provinces' => '[data-test-provinces]', + 'last_province' => '[data-test-provinces] [data-test-province]:last-child', + 'add_province' => '[data-test-add-province]', 'form' => 'form', - 'provinces' => '#sylius_country_provinces', ]); } - private function getLastProvinceElement(): NodeElement + private function getProvinceItems(): array { - $provinces = $this->getElement('provinces'); - $items = $provinces->findAll('css', 'div[data-form-collection="item"]'); + $items = $this->getElement('provinces')->findAll('css', '[data-test-province]'); + Assert::isArray($items); - Assert::notEmpty($items); + return $items; + } - return end($items); + private function getProvinceElement(string $provinceName): NodeElement|null + { + return $this->getDocument()->find('xpath', sprintf('//*[@data-test-province and .//*[contains(@value, \'%s\')]]', $provinceName)); } } diff --git a/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php index 37fa7677af..69592dc510 100644 --- a/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Country/UpdatePageInterface.php @@ -23,22 +23,20 @@ interface UpdatePageInterface extends BaseUpdatePageInterface public function isCodeFieldDisabled(): bool; + public function addProvince(): void; + + public function specifyProvinceName(string $name): void; + + public function specifyProvinceCode(string $code): void; + + public function specifyProvinceAbbreviation(string $abbreviation): void; + public function isThereProvince(string $provinceName): bool; public function isThereProvinceWithCode(string $provinceCode): bool; - public function addProvince(string $name, string $code, ?string $abbreviation = null): void; - public function removeProvince(string $provinceName): void; - public function clickAddProvinceButton(): void; - - public function nameProvince(string $provinceName): void; - - public function removeProvinceName(string $provinceName): void; - - public function specifyProvinceCode(string $provinceCode): void; - /** @return array */ public function getFormValidationErrors(): array; } diff --git a/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php b/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php index e5df0c285e..f4a9777280 100644 --- a/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/Crud/CreatePage.php @@ -19,6 +19,7 @@ use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Session; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage; use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; +use Sylius\Behat\Service\DriverHelper; use Symfony\Component\Routing\RouterInterface; class CreatePage extends SymfonyPage implements CreatePageInterface @@ -34,6 +35,9 @@ class CreatePage extends SymfonyPage implements CreatePageInterface public function create(): void { + if (DriverHelper::isJavascript($this->getDriver())) { + $this->getDocument()->find('css', 'body')->click(); + } $this->getDocument()->pressButton('Create'); } @@ -44,9 +48,9 @@ class CreatePage extends SymfonyPage implements CreatePageInterface throw new ElementNotFoundException($this->getSession(), 'Field element'); } - $validationMessage = $foundElement->find('css', '.sylius-validation-error'); + $validationMessage = $foundElement->find('css', '.invalid-feedback'); if (null === $validationMessage) { - throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); } return $validationMessage->getText(); diff --git a/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php b/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php index d85544cdee..ddd03bd7e1 100644 --- a/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php +++ b/src/Sylius/Behat/Page/Admin/Crud/IndexPage.php @@ -98,7 +98,7 @@ class IndexPage extends SymfonyPage implements IndexPageInterface $deletedRow = $tableAccessor->getRowWithFields($table, $parameters); $actionButtons = $tableAccessor->getFieldFromRow($table, $deletedRow, 'actions'); - $actionButtons->pressButton('Delete'); + $actionButtons->pressButton('delete'); } public function getActionsForResource(array $parameters): NodeElement @@ -117,7 +117,7 @@ class IndexPage extends SymfonyPage implements IndexPageInterface $table = $this->getElement('table'); $resourceRow = $tableAccessor->getRowWithFields($table, $parameters); - $bulkCheckbox = $resourceRow->find('css', '.bulk-select-checkbox'); + $bulkCheckbox = $resourceRow->find('css', '.form-check-input'); Assert::notNull($bulkCheckbox); @@ -160,13 +160,30 @@ class IndexPage extends SymfonyPage implements IndexPageInterface return $this->tableAccessor; } + protected function toggleFilters(): void + { + $filtersToggle = $this->getElement('filters_toggle'); + $filtersToggle->click(); + $this->getDocument()->waitFor(1, function () use ($filtersToggle) { + $accordionCollapse = $filtersToggle->find('css', '.accordion-collapse'); + + return null !== $accordionCollapse && !$accordionCollapse->hasClass('collapsing'); + }); + } + + protected function areFiltersVisible(): bool + { + return !$this->getElement('filters_toggle')->hasClass('collapsed'); + } + protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ 'bulk_actions' => '.sylius-grid-nav__bulk', - 'confirmation_button' => '#confirmation-button', + 'confirmation_button' => '[data-confirm-btn-true]', 'enabled_filter' => '#criteria_enabled', - 'filter' => 'button:contains("Filter")', + 'filter' => '[data-test-filter]', + 'filters_toggle' => '.accordion-button', 'table' => '.table', ]); } diff --git a/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php index af2989c39a..127d5ce6d7 100644 --- a/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Crud/UpdatePage.php @@ -19,6 +19,7 @@ use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Session; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage; use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; +use Sylius\Behat\Service\DriverHelper; use Sylius\Component\Core\Formatter\StringInflector; use Symfony\Component\Routing\RouterInterface; @@ -28,14 +29,17 @@ class UpdatePage extends SymfonyPage implements UpdatePageInterface Session $session, $minkParameters, RouterInterface $router, - private string $routeName, + private readonly string $routeName, ) { parent::__construct($session, $minkParameters, $router); } public function saveChanges(): void { - $this->getDocument()->pressButton('sylius_save_changes_button'); + if (DriverHelper::isJavascript($this->getDriver())) { + $this->getDocument()->find('css', 'body')->click(); + } + $this->getDocument()->find('css', '[data-test-update-changes-button]')->click(); } public function cancelChanges(): void @@ -50,14 +54,17 @@ class UpdatePage extends SymfonyPage implements UpdatePageInterface throw new ElementNotFoundException($this->getSession(), 'Field element'); } - $validationMessage = $foundElement->find('css', '.sylius-validation-error'); + $validationMessage = $foundElement->find('css', '.invalid-feedback'); if (null === $validationMessage) { - throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); } return $validationMessage->getText(); } + /** + * @param array $parameters + */ public function hasResourceValues(array $parameters): bool { foreach ($parameters as $element => $value) { @@ -100,7 +107,7 @@ class UpdatePage extends SymfonyPage implements UpdatePageInterface /** * @throws ElementNotFoundException */ - private function getFieldElement(string $element): ?NodeElement + private function getFieldElement(string $element): NodeElement { $element = $this->getElement(StringInflector::nameToCode($element)); while (null !== $element && !$element->hasClass('field')) { diff --git a/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php b/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php index 1e6b4c791e..6093a2fa61 100644 --- a/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php +++ b/src/Sylius/Behat/Page/Admin/Customer/IndexPage.php @@ -13,12 +13,26 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Customer; +use Behat\Mink\Session; use Sylius\Behat\Page\Admin\Crud\IndexPage as BaseIndexPage; -use Sylius\Behat\Service\AutocompleteHelper; +use Sylius\Behat\Service\Accessor\TableAccessorInterface; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Component\Customer\Model\CustomerInterface; +use Symfony\Component\Routing\RouterInterface; class IndexPage extends BaseIndexPage implements IndexPageInterface { + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + TableAccessorInterface $tableAccessor, + string $routeName, + private AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $tableAccessor, $routeName); + } + public function getCustomerAccountStatus(CustomerInterface $customer): string { $tableAccessor = $this->getTableAccessor(); @@ -39,17 +53,37 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface return $tableAccessor->getFieldFromRow($table, $row, 'verified')->getText() === 'Yes'; } - public function specifyFilterGroup(string $groupName): void + public function setFilterGroup(string $groupName): void { - $groupFilterElement = $this->getElement('filter_group')->getParent(); + $this->autocompleteHelper->selectByName( + $this->getDriver(), + $this->getElement('filter_group')->getXpath(), + $groupName, + ); - AutocompleteHelper::chooseValue($this->getSession(), $groupFilterElement, $groupName); + $this->waitForFormUpdate(); + } + + public function setFilterSearch(string $phrase): void + { + $this->getElement('filter_search')->setValue($phrase); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ 'filter_group' => '#criteria_group', + 'filter_search' => '#criteria_search_value', + 'filters_form' => '[data-test-filters-form]', ]); } + + private function waitForFormUpdate(): void + { + $form = $this->getElement('filters_form'); + sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute + $form->waitFor(1500, function () use ($form) { + return !$form->hasAttribute('busy'); + }); + } } diff --git a/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php b/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php index a1ef8dd3e7..20f91c4b49 100644 --- a/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Customer/IndexPageInterface.php @@ -22,5 +22,7 @@ interface IndexPageInterface extends BaseIndexPageInterface public function isCustomerVerified(CustomerInterface $customer): bool; - public function specifyFilterGroup(string $groupName): void; + public function setFilterGroup(string $groupName): void; + + public function setFilterSearch(string $phrase): void; } diff --git a/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php b/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php index 1b1e5cbefb..0b8254214d 100644 --- a/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php +++ b/src/Sylius/Behat/Page/Admin/Customer/ShowPage.php @@ -13,23 +13,13 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Customer; -use Behat\Mink\Element\NodeElement; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage; -use Webmozart\Assert\Assert; class ShowPage extends SymfonyPage implements ShowPageInterface { - public function isRegistered(): bool - { - $username = $this->getDocument()->find('css', '#username'); - - return null !== $username; - } - public function deleteAccount(): void { - $deleteButton = $this->getElement('delete_account_button'); - $deleteButton->pressButton('Delete'); + $this->getElement('delete_account_button')->press(); } public function getCustomerEmail(): string @@ -49,7 +39,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function getRegistrationDate(): \DateTimeInterface { - return new \DateTime(str_replace('Customer since ', '', $this->getElement('registration_date')->getText())); + return \DateTime::createFromFormat('d-m-Y H:i:s', $this->getElement('registration_date')->getText()); } public function getDefaultAddress(): string @@ -59,17 +49,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasAccount(): bool { - return $this->hasElement('no_account'); + return $this->hasElement('delete_account_button'); } public function isSubscribedToNewsletter(): bool { - $subscribedToNewsletter = $this->getElement('subscribed_to_newsletter'); - if ($subscribedToNewsletter->find('css', 'i.green')) { - return true; - } - - return false; + return null !== $this->getElement('subscribed_to_newsletter')->find('css', 'svg.text-green'); } public function hasDefaultAddressProvinceName(string $provinceName): bool @@ -81,23 +66,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasVerifiedEmail(): bool { - $verifiedEmail = $this->getElement('verified_email'); - if ($verifiedEmail->find('css', 'i.green')) { - return true; - } - - return false; + return null !== $this->getElement('verified_email')->find('css', 'svg.text-green'); } public function getGroupName(): string { - $group = $this->getElement('group'); - - Assert::notNull($group, 'There should be element group on page.'); - - [$text, $groupName] = explode(':', $group->getText()); - - return trim($groupName); + return $this->getElement('group')->getText(); } public function hasEmailVerificationInformation(): bool @@ -117,34 +91,22 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasCustomerPlacedAnyOrders(): bool { - return null !== $this->getElement('statistics')->find('css', '.sylius-orders-overall-count'); + return !$this->hasElement('statistics_no_orders'); } - public function getOrdersCountInChannel(string $channelName): int + public function getOrdersCountInChannel(string $channelCode): int { - return (int) $this - ->getStatisticsForChannel($channelName) - ->find('css', '.sylius-orders-count') - ->getText() - ; + return (int) $this->getElement('statistics_orders_count', ['%channelCode%' => $channelCode])->getText(); } - public function getOrdersTotalInChannel(string $channelName): string + public function getOrdersTotalInChannel(string $channelCode): string { - return $this - ->getStatisticsForChannel($channelName) - ->find('css', '.sylius-orders-total') - ->getText() - ; + return $this->getElement('statistics_orders_total', ['%channelCode%' => $channelCode])->getText(); } - public function getAverageTotalInChannel(string $channelName): string + public function getAverageTotalInChannel(string $channelCode): string { - return $this - ->getStatisticsForChannel($channelName) - ->find('css', '.sylius-order-average-total') - ->getText() - ; + return $this->getElement('statistics_orders_average', ['%channelCode%' => $channelCode])->getText(); } public function getSuccessFlashMessage(): string @@ -160,48 +122,20 @@ class ShowPage extends SymfonyPage implements ShowPageInterface protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'customer_email' => '#info .content.extra > a', - 'customer_name' => '#info .content > a', - 'customer_phone_number' => '#phone-number', - 'default_address' => '#default-address', - 'delete_account_button' => '#actions', - 'flash_message' => '.ui.icon.positive.message .content p', - 'group' => '.group', - 'impersonate_button' => '#impersonate', - 'no_account' => '#no-account', - 'statistics' => '#statistics', - 'registration_date' => '#info .content .date', - 'subscribed_to_newsletter' => '#subscribed-to-newsletter', - 'verified_email' => '#verified-email', + 'customer_email' => '[data-test-customer-email]', + 'customer_name' => '[data-test-customer-fullname]', + 'customer_phone_number' => '[data-test-customer-phone]', + 'default_address' => '[data-test-customer-default-address]', + 'delete_account_button' => '[data-test-customer-actions-delete]', + 'group' => '[data-test-customer-group]', + 'impersonate_button' => '[data-test-customer-actions-impersonate]', + 'registration_date' => '[data-test-customer-since]', + 'statistics_no_orders' => '[data-test-customer-statistics-no-orders]', + 'statistics_orders_average' => '[data-test-customer-statistics-%channelCode%-orders-average]', + 'statistics_orders_count' => '[data-test-customer-statistics-%channelCode%-orders-count]', + 'statistics_orders_total' => '[data-test-customer-statistics-%channelCode%-orders-total]', + 'subscribed_to_newsletter' => '[data-test-customer-subscribed-to-newsletter]', + 'verified_email' => '[data-test-customer-verified-email]', ]); } - - /** - * @throws \InvalidArgumentException - */ - private function getStatisticsForChannel(string $channelName): NodeElement - { - $statisticsRibs = $this - ->getElement('statistics') - ->findAll('css', '.row > .column > .statistic > .sylius-channel-name') - ; - - $statisticsRibs = array_filter($statisticsRibs, fn (NodeElement $statistic) => $channelName === trim($statistic->getText())); - - $actualStatisticsCount = count($statisticsRibs); - Assert::same( - 1, - $actualStatisticsCount, - sprintf( - 'Expected a single statistic for channel "%s", but %d were found.', - $channelName, - $actualStatisticsCount, - ), - ); - - $statisticsContents = $this->getElement('statistics')->findAll('css', '.row'); - $contentIndexes = array_keys($statisticsRibs); - - return $statisticsContents[reset($contentIndexes)]; - } } diff --git a/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php b/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php index 8b93e8010f..668d457431 100644 --- a/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Customer/ShowPageInterface.php @@ -13,16 +13,10 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Customer; -use Behat\Mink\Exception\ElementNotFoundException; use FriendsOfBehat\PageObjectExtension\Page\PageInterface; interface ShowPageInterface extends PageInterface { - public function isRegistered(): bool; - - /** - * @throws ElementNotFoundException If there is no delete account button on the page - */ public function deleteAccount(): void; public function getCustomerEmail(): string; @@ -53,11 +47,11 @@ interface ShowPageInterface extends PageInterface public function hasCustomerPlacedAnyOrders(): bool; - public function getOrdersCountInChannel(string $channelName): int; + public function getOrdersCountInChannel(string $channelCode): int; - public function getOrdersTotalInChannel(string $channelName): string; + public function getOrdersTotalInChannel(string $channelCode): string; - public function getAverageTotalInChannel(string $channelName): string; + public function getAverageTotalInChannel(string $channelCode): string; public function getSuccessFlashMessage(): string; } diff --git a/src/Sylius/Behat/Page/Admin/DashboardPage.php b/src/Sylius/Behat/Page/Admin/DashboardPage.php index c639bf66be..fed132d0bf 100644 --- a/src/Sylius/Behat/Page/Admin/DashboardPage.php +++ b/src/Sylius/Behat/Page/Admin/DashboardPage.php @@ -138,7 +138,7 @@ class DashboardPage extends SymfonyPage implements DashboardPageInterface 'channel_choosing_link' => 'a:contains("%channelName%")', 'customer_list' => '#customers', 'dropdown' => 'i.dropdown', - 'logout' => '#sylius-logout-button', + 'logout' => '[data-test-user-dropdown-item="Logout"]', 'month_split_by_days_statistics_button' => 'button[data-stats-button="month"]', 'navigation_next' => '#navigation-next', 'navigation_previous' => '#navigation-prev', diff --git a/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php b/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php index a694a6cf3f..9f0946d18b 100644 --- a/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php +++ b/src/Sylius/Behat/Page/Admin/Order/HistoryPage.php @@ -22,13 +22,21 @@ class HistoryPage extends SymfonyPage implements HistoryPageInterface return 'sylius_admin_order_history'; } - public function countShippingAddressChanges(): int - { - return count($this->getDocument()->findAll('css', '#shipping-address-changes tbody tr')); - } - public function countBillingAddressChanges(): int { - return count($this->getDocument()->findAll('css', '#billing-address-changes tbody tr')); + return count($this->getElement('billing_address_logs')->findAll('css', '[data-test-address-log]')); + } + + public function countShippingAddressChanges(): int + { + return count($this->getElement('shipping_address_logs')->findAll('css', '[data-test-address-log]')); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'billing_address_logs' => '[data-test-address-type="Billing address"]', + 'shipping_address_logs' => '[data-test-address-type="Shipping address"]', + ]); } } diff --git a/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php b/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php index 10d174abab..38daaa0121 100644 --- a/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Order/HistoryPageInterface.php @@ -17,7 +17,7 @@ use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface; interface HistoryPageInterface extends SymfonyPageInterface { - public function countShippingAddressChanges(): int; - public function countBillingAddressChanges(): int; + + public function countShippingAddressChanges(): int; } diff --git a/src/Sylius/Behat/Page/Admin/Order/ShowPage.php b/src/Sylius/Behat/Page/Admin/Order/ShowPage.php index 991da2ff16..efa4e7f274 100644 --- a/src/Sylius/Behat/Page/Admin/Order/ShowPage.php +++ b/src/Sylius/Behat/Page/Admin/Order/ShowPage.php @@ -18,7 +18,6 @@ use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Session; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage; use Sylius\Behat\Service\Accessor\TableAccessorInterface; -use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface; use Sylius\Component\Core\Model\OrderInterface; use Symfony\Component\Routing\RouterInterface; @@ -29,7 +28,6 @@ class ShowPage extends SymfonyPage implements ShowPageInterface $minkParameters, RouterInterface $router, private TableAccessorInterface $tableAccessor, - private MoneyFormatterInterface $moneyFormatter, ) { parent::__construct($session, $minkParameters, $router); } @@ -66,48 +64,65 @@ class ShowPage extends SymfonyPage implements ShowPageInterface return $this->hasAddress($billingAddressText, $customerName, $street, $postcode, $city, $countryName); } - public function hasShipment(string $shippingDetails): bool + public function hasShipment(string $shippingMethodName): bool { $shipmentsText = $this->getElement('shipments')->getText(); - return stripos($shipmentsText, $shippingDetails) !== false; + return stripos($shipmentsText, $shippingMethodName) !== false; + } + + public function hasShipmentWithState(string $state): bool + { + foreach ($this->getElement('shipments')->findAll('css', '[data-test-shipment-state]') as $shipmentState) { + if (0 === strcasecmp($state, $shipmentState->getText())) { + return true; + } + } + + return false; } public function specifyTrackingCode(string $code): void { - $this->getDocument()->fillField('sylius_shipment_ship_tracking', $code); + $this->getElement('shipment_tracking')->setValue($code); } public function canShipOrder(OrderInterface $order): bool { - return $this->getLastOrderShipmentElement($order)->hasButton('Ship'); + return $this->hasElement('shipment_ship_button'); } public function shipOrder(OrderInterface $order): void { - $this->getLastOrderShipmentElement($order)->pressButton('Ship'); + $this->getElement('shipment_ship_button')->press(); } - public function hasPayment(string $paymentDetails): bool + public function hasPayment(string $paymentMethodName): bool { $paymentsText = $this->getElement('payments')->getText(); - return stripos($paymentsText, $paymentDetails) !== false; + return stripos($paymentsText, $paymentMethodName) !== false; } public function canCompleteOrderLastPayment(OrderInterface $order): bool { - return $this->getLastOrderPaymentElement($order)->hasButton('Complete'); + $lastPayment = $order->getLastPayment(); + + return $this->hasElement('payment_complete', ['%paymentId%' => $lastPayment->getId()]); } public function completeOrderLastPayment(OrderInterface $order): void { - $this->getLastOrderPaymentElement($order)->pressButton('Complete'); + $lastPayment = $order->getLastPayment(); + + $this->getElement('payment_complete', ['%paymentId%' => $lastPayment->getId()])->submit(); } public function refundOrderLastPayment(OrderInterface $order): void { - $this->getLastOrderPaymentElement($order)->pressButton('Refund'); + $lastPayment = $order->getLastPayment(); + + $this->getElement('payment_refund', ['%paymentId%' => $lastPayment->getId()])->submit(); } public function countItems(): int @@ -269,18 +284,14 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function getPaymentAmount(): string { - $paymentsPrice = $this->getElement('payments')->find('css', '.description'); + $paymentsPrice = $this->getElement('payments')->find('css', '[data-test-payment-amount]'); return $paymentsPrice->getText(); } public function getPaymentsCount(): int { - try { - $payments = $this->getElement('payments')->findAll('css', '.item'); - } catch (ElementNotFoundException) { - return 0; - } + $payments = $this->getElement('payments')->findAll('css', '[data-test-payment]'); return count($payments); } @@ -298,7 +309,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function hasCancelButton(): bool { - return $this->getDocument()->hasButton('Cancel'); + return $this->hasElement('cancel_order'); + } + + public function cancelOrder(): void + { + $this->getElement('cancel_order')->click(); } public function getOrderState(): string @@ -316,11 +332,6 @@ class ShowPage extends SymfonyPage implements ShowPageInterface return $this->getElement('order_shipping_state')->getText(); } - public function cancelOrder(): void - { - $this->getDocument()->pressButton('Cancel'); - } - public function deleteOrder(): void { $this->getDocument()->pressButton('Delete'); @@ -405,32 +416,37 @@ class ShowPage extends SymfonyPage implements ShowPageInterface protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'billing_address' => '#billing-address', + 'billing_address' => '[data-test-billing-address]', + 'cancel_order' => '[data-test-cancel-order]', 'currency' => '#sylius-order-currency', 'customer' => '#customer', 'ip_address' => '#ipAddress', 'items_total' => '#items-total', 'order_notes' => '#sylius-order-notes', - 'order_payment_state' => '#payment-state > span', + 'order_payment_state' => '[data-test-order-payment-state]', 'order_shipping_state' => '#shipping-state > span', - 'order_state' => '#sylius-order-state', - 'payments' => '#sylius-payments', + 'order_state' => '[data-test-order-state]', + 'payments' => '[data-test-payments]', + 'payment_complete' => '[data-test-complete-payment="%paymentId%"]', + 'payment_refund' => '[data-test-refund-payment="%paymentId%"]', 'promotion_discounts' => '#promotion-discounts', 'promotion_shipping_discounts' => '#shipping-discount-value', - 'promotion_total' => '#promotion-total', + 'promotion_total' => '[data-test-promotion-total]', 'resend_order_confirmation_email' => '[data-test-resend-order-confirmation-email]', 'resend_shipment_confirmation_email' => '[data-test-resend-shipment-confirmation-email]', 'shipment_shipped_at_date' => '#sylius-shipments .shipped-at-date', - 'shipments' => '#sylius-shipments', - 'shipping_address' => '#shipping-address', + 'shipments' => '[data-test-shipments]', + 'shipment_tracking' => '[data-test-shipment-tracking]', + 'shipment_ship_button' => '[data-test-shipment-ship-button]', + 'shipping_address' => '[data-test-shipping-address]', 'shipping_adjustment_name' => '#shipping-adjustment-label', 'shipping_charges' => '#shipping-base-value', 'shipping_tax' => '#shipping-tax-value', 'shipping_total' => '#shipping-total', 'table' => '.table', - 'tax_total' => '#tax-total', + 'tax_total' => '[data-test-tax-total]', 'taxes' => '#taxes', - 'total' => '#total', + 'total' => '[data-test-total]', ]); } @@ -463,29 +479,4 @@ class ShowPage extends SymfonyPage implements ShowPageInterface { return $this->tableAccessor->getRowWithFields($this->getElement('table'), ['item' => $itemName]); } - - protected function getLastOrderPaymentElement(OrderInterface $order): ?NodeElement - { - $payment = $order->getPayments()->last(); - - $paymentStateElements = $this->getElement('payments')->findAll('css', sprintf('span.ui.label:contains(\'%s\')', ucfirst($payment->getState()))); - $paymentStateElement = end($paymentStateElements); - - return $paymentStateElement->getParent()->getParent(); - } - - protected function getLastOrderShipmentElement(OrderInterface $order): ?NodeElement - { - $shipment = $order->getShipments()->last(); - - $shipmentStateElements = $this->getElement('shipments')->findAll('css', sprintf('span.ui.label:contains(\'%s\')', ucfirst($shipment->getState()))); - $shipmentStateElement = end($shipmentStateElements); - - return $shipmentStateElement->getParent()->getParent(); - } - - protected function getFormattedMoney(int $orderPromotionTotal): string - { - return $this->moneyFormatter->format($orderPromotionTotal, $this->getDocument()->find('css', '#sylius-order-currency')->getText()); - } } diff --git a/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php b/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php index 9fbd74a36a..012aca9f59 100644 --- a/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Order/ShowPageInterface.php @@ -28,6 +28,8 @@ interface ShowPageInterface extends SymfonyPageInterface public function hasShipment(string $shippingMethodName): bool; + public function hasShipmentWithState(string $state); + public function specifyTrackingCode(string $code): void; public function canShipOrder(OrderInterface $order): bool; diff --git a/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php index 356269d3ee..98e6471e92 100644 --- a/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Order/UpdatePage.php @@ -52,17 +52,47 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface { $foundElement = $this->getFieldElement($element); if (null === $foundElement) { - throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); } - $validationMessage = $foundElement->find('css', '.sylius-validation-error'); + $validationMessage = $foundElement->find('css', '.invalid-feedback'); if (null === $validationMessage) { - throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); } return $message === $validationMessage->getText(); } + public function changeBillingCountry(string $countryCode): void + { + $this->getElement('billing_country')->selectOption($countryCode); + $this->waitForFormUpdate(); + } + + public function changeShippingCountry(string $countryCode): void + { + $this->getElement('shipping_country')->selectOption($countryCode); + $this->waitForFormUpdate(); + } + + public function getAvailableProvincesForBillingAddress(): array + { + return $this->getOptionTextsFor($this->getElement('billing_province_code')); + } + + public function getAvailableProvincesForShippingAddress(): array + { + return $this->getOptionTextsFor($this->getElement('shipping_province_code')); + } + + /** + * @return array + */ + private function getOptionTextsFor(NodeElement $element): array + { + return array_map(fn ($option) => $option->getText(), $element->findAll('css', 'option')); + } + protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ @@ -71,12 +101,17 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface 'billing_first_name' => '#sylius_order_billingAddress_firstName', 'billing_last_name' => '#sylius_order_billingAddress_lastName', 'billing_postcode' => '#sylius_order_billingAddress_postcode', + 'billing_province_name' => '#sylius_order_billingAddress_provinceName', + 'billing_province_code' => '#sylius_order_billingAddress_provinceCode', 'billing_street' => '#sylius_order_billingAddress_street', + 'live_form' => '[data-live-name-value="sylius_admin:order:form"]', 'shipping_city' => '#sylius_order_shippingAddress_city', 'shipping_country' => '#sylius_order_shippingAddress_countryCode', 'shipping_first_name' => '#sylius_order_shippingAddress_firstName', 'shipping_last_name' => '#sylius_order_shippingAddress_lastName', 'shipping_postcode' => '#sylius_order_shippingAddress_postcode', + 'shipping_province_name' => '#sylius_order_shippingAddress_provinceName', + 'shipping_province_code' => '#sylius_order_shippingAddress_provinceCode', 'shipping_street' => '#sylius_order_shippingAddress_street', ]); } @@ -109,4 +144,9 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return $element; } + + private function waitForFormUpdate(): void + { + $this->getElement('live_form')->waitFor('5', fn (NodeElement $element) => !$element->hasAttribute('busy')); + } } diff --git a/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php index 43c4720dc0..047d58c231 100644 --- a/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Order/UpdatePageInterface.php @@ -23,4 +23,18 @@ interface UpdatePageInterface extends BaseUpdatePageInterface public function specifyBillingAddress(AddressInterface $address): void; public function checkValidationMessageFor(string $element, string $message): bool; + + public function changeBillingCountry(string $countryCode): void; + + public function changeShippingCountry(string $countryCode): void; + + /** + * @return array + */ + public function getAvailableProvincesForBillingAddress(): array; + + /** + * @return array + */ + public function getAvailableProvincesForShippingAddress(): array; } diff --git a/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php b/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php index e14563a21a..7c1ed6e234 100644 --- a/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/PaymentMethod/CreatePage.php @@ -99,6 +99,9 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface return $this->getElement('enabled'); } + /** + * @return array + */ protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ diff --git a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php index 3f0bcf5c32..6996269a53 100644 --- a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePage.php @@ -38,16 +38,36 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface $this->getDocument()->fillField('Signature', $signature); } + public function setStripeSecretKey(string $secretKey): void + { + $this->getDocument()->fillField('Secret key', $secretKey); + } + + public function setStripePublishableKey(string $publishableKey): void + { + $this->getDocument()->fillField('Publishable key', $publishableKey); + } + public function nameIt(string $name, string $languageCode): void { $this->getDocument()->fillField(sprintf('sylius_payment_method_translations_%s_name', $languageCode), $name); } + public function enableSandboxMode(): void + { + $this->getElement('sandbox')->check(); + } + public function isPaymentMethodEnabled(): bool { return (bool) $this->getToggleableElement()->getValue(); } + public function isPaymentMethodInSandboxMode(): bool + { + return $this->getElement('sandbox')->hasAttribute('checked'); + } + public function isFactoryNameFieldDisabled(): bool { return 'disabled' === $this->getElement('factory_name')->getAttribute('disabled'); @@ -55,7 +75,10 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface public function isAvailableInChannel(string $channelName): bool { - return $this->getElement('channel', ['%channel%' => $channelName])->hasAttribute('checked'); + return $this + ->getElement('channel', ['%channel_name%' => $channelName]) + ->hasAttribute('checked') + ; } public function getPaymentMethodInstructions(string $language): string @@ -73,15 +96,24 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return $this->getElement('enabled'); } + /** + * @return array + */ protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'channel' => '.checkbox:contains("%channel%") input', - 'code' => '#sylius_payment_method_code', - 'enabled' => '#sylius_payment_method_enabled', - 'factory_name' => '#sylius_payment_method_gatewayConfig_factoryName', + 'channel' => '[data-test-channel-name="%channel_name%"]', + 'code' => '[data-test-code]', + 'enabled' => '[data-test-enabled]', + 'factory_name' => '[data-test-factory-name]', 'instructions' => '#sylius_payment_method_translations_%language%_instructions', 'name' => '#sylius_payment_method_translations_en_US_name', + 'password' => '[data-test-password]', + 'publishable_key' => '[data-test-publishable-key]', + 'sandbox' => '[data-test-sandbox]', + 'secret_key' => '[data-test-secret-key]', + 'signature' => '[data-test-signature]', + 'username' => '[data-test-username]', ]); } } diff --git a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php index 4aeb384583..40696b9c0d 100644 --- a/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/PaymentMethod/UpdatePageInterface.php @@ -29,12 +29,20 @@ interface UpdatePageInterface extends BaseUpdatePageInterface public function setPaypalGatewaySignature(string $signature): void; + public function enableSandboxMode(): void; + + public function setStripeSecretKey(string $secretKey): void; + + public function setStripePublishableKey(string $publishableKey): void; + public function isCodeDisabled(): bool; public function isFactoryNameFieldDisabled(): bool; public function isPaymentMethodEnabled(): bool; + public function isPaymentMethodInSandboxMode(): bool; + public function isAvailableInChannel(string $channelName): bool; public function getPaymentMethodInstructions(string $language): string; diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php index 080b49c528..de4fb44686 100644 --- a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php +++ b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPage.php @@ -14,31 +14,36 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Product; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; use Sylius\Behat\Behaviour\SpecifiesItsField; use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; use Sylius\Behat\Service\AutocompleteHelper; use Sylius\Behat\Service\DriverHelper; -use Sylius\Behat\Service\SlugGenerationHelper; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Component\Core\Model\TaxonInterface; +use Symfony\Component\Routing\RouterInterface; use Webmozart\Assert\Assert; class CreateConfigurableProductPage extends BaseCreatePage implements CreateConfigurableProductPageInterface { use SpecifiesItsField; + use FormTrait; - public function nameItIn(string $name, string $localeCode): void + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + string $routeName, + private readonly AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $routeName); + } + + public function create(): void { - $this->clickTabIfItsNotActive('details'); - $this->activateLanguageTab($localeCode); + $this->waitForFormUpdate(); - $this->getDocument()->fillField( - sprintf('sylius_product_translations_%s_name', $localeCode), - $name, - ); - - if (DriverHelper::isJavascript($this->getDriver())) { - SlugGenerationHelper::waitForSlugGeneration($this->getSession(), $this->getElement('slug')); - } + parent::create(); } public function hasMainTaxonWithName(string $taxonName): bool @@ -58,29 +63,6 @@ class CreateConfigurableProductPage extends BaseCreatePage implements CreateConf AutocompleteHelper::chooseValue($this->getSession(), $mainTaxonElement, $taxon->getName()); } - public function selectOption(string $optionName): void - { - $option = $this->getElement('options_choice')->getParent(); - - AutocompleteHelper::chooseValue($this->getSession(), $option, $optionName); - } - - public function attachImage(string $path, ?string $type = null): void - { - $this->clickTabIfItsNotActive('media'); - - $filesPath = $this->getParameter('files_path'); - - $this->getDocument()->clickLink('Add'); - - $imageForm = $this->getLastImageElement(); - if (null !== $type) { - $imageForm->fillField('Type', $type); - } - - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - public function activateLanguageTab(string $localeCode): void { if (DriverHelper::isNotJavascript($this->getDriver())) { @@ -104,20 +86,24 @@ class CreateConfigurableProductPage extends BaseCreatePage implements CreateConf protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'attribute' => '.attribute', - 'code' => '#sylius_product_code', - 'images' => '#sylius_product_images', - 'language_tab' => '[data-locale="%localeCode%"] .title', - 'main_taxon' => '#sylius_product_mainTaxon', - 'name' => '#sylius_product_translations_en_US_name', - 'options_choice' => '#sylius_product_options', - 'search' => '.ui.fluid.search.selection.dropdown', - 'search_item_selected' => 'div.menu > div.item.selected', - 'slug' => '#sylius_product_translations_en_US_slug', - 'tab' => '.menu [data-tab="%name%"]', - 'taxonomy' => 'a[data-tab="taxonomy"]', - ]); + return array_merge( + parent::getDefinedElements(), + [ + 'attribute' => '.attribute', + 'code' => '#sylius_product_code', + 'images' => '#sylius_product_images', + 'language_tab' => '[data-locale="%localeCode%"] .title', + 'main_taxon' => '#sylius_product_mainTaxon', + 'name' => '#sylius_product_translations_en_US_name', + 'options_choice' => '#sylius_product_options', + 'search' => '.ui.fluid.search.selection.dropdown', + 'search_item_selected' => 'div.menu > div.item.selected', + 'slug' => '#sylius_product_translations_en_US_slug', + 'tab' => '.menu [data-tab="%name%"]', + 'taxonomy' => 'a[data-tab="taxonomy"]', + ], + $this->getDefinedFormElements(), + ); } private function openTaxonBookmarks(): void diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php index ea132c78d9..66a75b0ab6 100644 --- a/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Product/CreateConfigurableProductPageInterface.php @@ -28,6 +28,8 @@ interface CreateConfigurableProductPageInterface extends BaseCreatePageInterface public function selectMainTaxon(TaxonInterface $taxon): void; + public function hasImageWithType(string $type): bool; + public function attachImage(string $path, ?string $type = null): void; public function activateLanguageTab(string $localeCode): void; diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php index 3cd8e39a47..4d521c2161 100644 --- a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php +++ b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPage.php @@ -14,37 +14,41 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Product; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; use Sylius\Behat\Behaviour\SpecifiesItsField; use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; use Sylius\Behat\Service\AutocompleteHelper; use Sylius\Behat\Service\DriverHelper; -use Sylius\Behat\Service\SlugGenerationHelper; -use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Component\Core\Model\TaxonInterface; -use Sylius\Component\Product\Model\ProductAssociationTypeInterface; +use Symfony\Component\Routing\RouterInterface; use Webmozart\Assert\Assert; class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProductPageInterface { + use FormTrait; use SpecifiesItsField; + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + string $routeName, + private readonly AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $routeName); + } + public function getRouteName(): string { return parent::getRouteName() . '_simple'; } - public function nameItIn(string $name, string $localeCode): void + public function create(): void { - $this->clickTabIfItsNotActive('details'); - $this->activateLanguageTab($localeCode); - $this->getElement('name', ['%locale%' => $localeCode])->setValue($name); + $this->waitForFormUpdate(); - if (DriverHelper::isJavascript($this->getDriver())) { - SlugGenerationHelper::waitForSlugGeneration( - $this->getSession(), - $this->getElement('slug', ['%locale%' => $localeCode]), - ); - } + parent::create(); } public function specifySlugIn(?string $slug, string $locale): void @@ -54,38 +58,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd $this->getElement('slug', ['%locale%' => $locale])->setValue($slug); } - public function specifyPrice(ChannelInterface $channel, string $price): void - { - $this->getElement('price', ['%channelCode%' => $channel->getCode()])->setValue($price); - } - - public function specifyOriginalPrice(ChannelInterface $channel, int $originalPrice): void - { - $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice); - } - - public function addAttribute(string $attributeName, string $value, string $localeCode): void - { - $this->clickTabIfItsNotActive('attributes'); - - $attributeOption = $this->getElement('attributes_choice')->find('css', sprintf('option:contains("%s")', $attributeName)); - $this->selectElementFromAttributesDropdown($attributeOption->getAttribute('value')); - - $this->getDocument()->pressButton('Add attributes'); - $this->waitForFormElement(); - - if ('' === $value) { - return; - } - - $this->getElement('attribute_value', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->setValue($value); - } - - public function selectAttributeValue(string $attributeName, string $value, string $localeCode): void - { - $this->getElement('attribute_value_select', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->selectOption($value); - } - public function addNonTranslatableAttribute(string $attributeName, string $value): void { $this->clickTabIfItsNotActive('attributes'); @@ -108,13 +80,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd return $validationError->getText(); } - public function removeAttribute(string $attributeName, string $localeCode): void - { - $this->clickTabIfItsNotActive('attributes'); - - $this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->press(); - } - public function checkAttributeErrors($attributeName, $localeCode): void { $this->clickTabIfItsNotActive('attributes'); @@ -152,56 +117,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd $productTaxonsElement->setValue(implode(',', $productTaxonsCodes)); } - public function attachImage(string $path, ?string $type = null): void - { - $this->clickTabIfItsNotActive('media'); - - $filesPath = $this->getParameter('files_path'); - - $this->getDocument()->clickLink('Add'); - - $imageForm = $this->getLastImageElement(); - if (null !== $type) { - $imageForm->fillField('Type', $type); - } - - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void - { - $this->clickTab('associations'); - - $dropdown = $this->getElement('association_dropdown', [ - '%association%' => $productAssociationType->getName(), - ]); - $dropdown->click(); - - foreach ($productsNames as $productName) { - $dropdown->waitFor(5, fn () => $this->hasElement('association_dropdown_item', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ])); - - $item = $this->getElement('association_dropdown_item', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ]); - $item->click(); - } - } - - public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void - { - $this->clickTabIfItsNotActive('associations'); - - $item = $this->getElement('association_dropdown_item_selected', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ]); - $item->find('css', 'i.delete')->click(); - } - public function choosePricingCalculator(string $name): void { $this->getElement('price_calculator')->selectOption($name); @@ -224,22 +139,6 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd } } - public function selectShippingCategory(string $shippingCategoryName): void - { - $this->getElement('shipping_category')->selectOption($shippingCategoryName); - } - - public function setShippingRequired(bool $isShippingRequired): void - { - if ($isShippingRequired) { - $this->getElement('shipping_required')->check(); - - return; - } - - $this->getElement('shipping_required')->uncheck(); - } - public function getChannelPricingValidationMessage(): string { return $this->getElement('prices_validation_message')->getText(); @@ -261,37 +160,41 @@ class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProd protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select', - 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")', - 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")', - 'attribute' => '.attribute', - 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button', - 'attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input', - 'attribute_value_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select', - 'attributes_choice' => '#sylius_product_attribute_choice', - 'cancel_button' => '[data-test-cancel-changes-button]', - 'channel_checkbox' => '.checkbox:contains("%channelName%") input', - 'code' => '#sylius_product_code', - 'form' => 'form[name="sylius_product"]', - 'images' => '#sylius_product_images', - 'language_tab' => '[data-locale="%locale%"] .title', - 'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]', - 'main_taxon' => '#sylius_product_mainTaxon', - 'product_taxons' => '#sylius_product_productTaxons', - 'name' => '#sylius_product_translations_%locale%_name', - 'non_translatable_attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input', - 'original_price' => '#sylius_product_variant_channelPricings_%channelCode%_originalPrice', - 'price' => '#sylius_product_variant_channelPricings_%channelCode%_price', - 'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error', - 'price_calculator' => '#sylius_product_variant_pricingCalculator', - 'shipping_category' => '#sylius_product_variant_shippingCategory', - 'shipping_required' => '#sylius_product_variant_shippingRequired', - 'slug' => '#sylius_product_translations_%locale%_slug', - 'tab' => '.menu [data-tab="%name%"]', - 'taxonomy' => 'a[data-tab="taxonomy"]', - 'toggle_slug_modification_button' => '.toggle-product-slug-modification', - ]); + return array_merge( + parent::getDefinedElements(), + [ + 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select', + 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")', + 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")', + 'attribute' => '.attribute', + 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button', + 'attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input', + 'attribute_value_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select', + 'attributes_choice' => '#sylius_product_attribute_choice', + 'cancel_button' => '[data-test-cancel-changes-button]', + 'channel_checkbox' => '.checkbox:contains("%channelName%") input', + 'code' => '#sylius_product_code', + 'form' => 'form[name="sylius_product"]', + 'images' => '#sylius_product_images', + 'language_tab' => '[data-locale="%locale%"] .title', + 'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]', + 'main_taxon' => '#sylius_product_mainTaxon', + 'product_taxons' => '#sylius_product_productTaxons', + 'name' => '#sylius_product_translations_%locale%_name', + 'non_translatable_attribute_value' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input', + 'original_price' => '#sylius_product_variant_channelPricings_%channelCode%_originalPrice', + 'price' => '#sylius_product_variant_channelPricings_%channelCode%_price', + 'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error', + 'price_calculator' => '#sylius_product_variant_pricingCalculator', + 'shipping_category' => '#sylius_product_variant_shippingCategory', + 'shipping_required' => '#sylius_product_variant_shippingRequired', + 'slug' => '#sylius_product_translations_%locale%_slug', + 'tab' => '.menu [data-tab="%name%"]', + 'taxonomy' => 'a[data-tab="taxonomy"]', + 'toggle_slug_modification_button' => '.toggle-product-slug-modification', + ], + $this->getDefinedFormElements(), + ); } private function openTaxonBookmarks(): void diff --git a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php index dfd9e1ff8c..c6a995de94 100644 --- a/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Product/CreateSimpleProductPageInterface.php @@ -15,6 +15,7 @@ namespace Sylius\Behat\Page\Admin\Product; use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Core\Model\ProductInterface; use Sylius\Component\Core\Model\TaxonInterface; use Sylius\Component\Product\Model\ProductAssociationTypeInterface; @@ -34,9 +35,9 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface public function specifySlugIn(?string $slug, string $locale): void; - public function addAttribute(string $attributeName, string $value, string $localeCode): void; + public function addAttribute(string $attributeName): void; - public function selectAttributeValue(string $attributeName, string $value, string $localeCode): void; + public function updateAttribute(string $attributeName, string $value, string $localeCode): void; public function addNonTranslatableAttribute(string $attributeName, string $value): void; @@ -50,6 +51,8 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface public function checkProductTaxon(TaxonInterface $taxon): void; + public function hasImageWithType(string $type): bool; + public function attachImage(string $path, ?string $type = null): void; /** @@ -57,7 +60,7 @@ interface CreateSimpleProductPageInterface extends BaseCreatePageInterface */ public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void; - public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void; + public function removeAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): void; public function activateLanguageTab(string $locale): void; diff --git a/src/Sylius/Behat/Page/Admin/Product/FormTrait.php b/src/Sylius/Behat/Page/Admin/Product/FormTrait.php new file mode 100644 index 0000000000..237dfa216a --- /dev/null +++ b/src/Sylius/Behat/Page/Admin/Product/FormTrait.php @@ -0,0 +1,404 @@ + '[data-test-attribute-value][data-test-locale-code="%localeCode%"][data-test-attribute-name="%attributeName%"]', + 'channel_tab' => '[data-test-channel-tab="%channelCode%"]', + 'form' => '[data-live-name-value="sylius_admin:product:form"]', + 'field_associations' => '[name="sylius_product[associations][%association%][]"]', + 'field_name' => '[name="sylius_product[translations][%localeCode%][name]"]', + 'field_slug' => '[name="sylius_product[translations][%localeCode%][slug]"]', + 'field_price' => '[name="sylius_product[variant][channelPricings][%channelCode%][price]"]', + 'field_original_price' => '[name="sylius_product[variant][channelPricings][%channelCode%][originalPrice]"]', + 'field_shipping_category' => '[name="sylius_product[variant][shippingCategory]"]', + 'field_shipping_required' => '[name="sylius_product[variant][shippingRequired]"]', + 'generate_product_slug_button' => '[data-test-generate-product-slug-button="%localeCode%"]', + 'images' => '[data-test-images]', + 'image_subform' => '[data-test-image-subform]', + 'image_subform_with_type' => '[data-test-image-subform][data-test-type="%type%"]', + 'images_subforms' => '[data-test-image-subforms]', + 'product_attribute_autocomplete' => '[data-test-product-attribute-autocomplete]', + 'product_attribute_delete_button' => '[data-test-product-attribute-delete-button="%attributeName%"]', + 'product_attribute_input' => 'input[name="product_attributes"]', + 'product_attribute_tab' => '[data-test-product-attribute-tab="%name%"]', + 'product_options_autocomplete' => '[data-test-product-options-autocomplete]', + 'product_translation_accordion' => '[data-test-product-translations-accordion="%localeCode%"]', + 'side_navigation_tab' => '[data-test-side-navigation-tab="%name%"]', + ]; + } + + /* + * Filling fields + */ + + public function nameItIn(string $name, string $localeCode): void + { + $this->changeTab('translations'); + $this->expandTranslationAccordion($localeCode); + $this->getElement('field_name', ['%localeCode%' => $localeCode])->setValue($name); + + if (DriverHelper::isJavascript($this->getDriver())) { + $this->getElement('generate_product_slug_button', ['%localeCode%' => $localeCode])->click(); + $this->waitForFormUpdate(); + } + } + + public function specifyPrice(ChannelInterface $channel, string $price): void + { + $this->changeTab('channel-pricing'); + $this->changeChannelTab($channel->getCode()); + $this->getElement('field_price', ['%channelCode%' => $channel->getCode()])->setValue($price); + } + + // TODO: Move to the Simple Product specific class + public function specifyOriginalPrice(ChannelInterface $channel, int $originalPrice): void + { + $this->changeTab('channel-pricing'); + $this->changeChannelTab($channel->getCode()); + $this->getElement('field_original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice); + } + + // TODO: Move to the Simple Product specific class + public function selectShippingCategory(string $shippingCategoryName): void + { + $this->changeTab('shipping'); + $this->getElement('field_shipping_category')->selectOption($shippingCategoryName); + } + + // TODO: Move to the Simple Product specific class + public function setShippingRequired(bool $isShippingRequired): void + { + $this->changeTab('details'); + + if ($isShippingRequired) { + $this->getElement('field_shipping_required')->check(); + + return; + } + + $this->getElement('field_shipping_required')->uncheck(); + } + + // TODO: Move to the Simple Product specific class + public function isShippingRequired(): bool + { + return $this->getElement('field_shipping_required')->isChecked(); + } + + // TODO: Move to the Configurable Product specific class + public function selectOption(string $optionName): void + { + $this->changeTab('details'); + $productOptionsAutocomplete = $this->getElement('product_options_autocomplete'); + + $this->autocompleteHelper->selectByName($this->getDriver(), $productOptionsAutocomplete->getXpath(), $optionName); + } + + public function hasTab(string $name): bool + { + return $this->hasElement('side_navigation_tab', ['%name%' => $name]); + } + + /* + * Tabs management + */ + + private function changeTab(string $tabName): void + { + $this->getElement('side_navigation_tab', ['%name%' => $tabName])->click(); + } + + private function changeChannelTab(string $channelCode): void + { + $this->getElement('channel_tab', ['%channelCode%' => $channelCode])->click(); + } + + private function changeAttributeTab(string $attributeName): void + { + $this->getElement('product_attribute_tab', ['%name%' => $attributeName])->click(); + } + + private function expandTranslationAccordion(string $localeCode): void + { + $translationAccordion = $this->getElement('product_translation_accordion', ['%localeCode%' => $localeCode]); + + if ($translationAccordion->getAttribute('aria-expanded') === 'true') { + return; + } + + $translationAccordion->click(); + } + + /* + * Attribute management + */ + + public function addAttribute(string $attributeName): void + { + $this->changeTab('attributes'); + $this->selectAttributeToBeAdded($attributeName); + $this->clickButton('Add'); + + $this->waitForFormUpdate(); + } + + public function updateAttribute(string $attributeName, string $value, string $localeCode): void + { + $this->changeTab('attributes'); + $this->changeAttributeTab($attributeName); + + $attributeValue = $this->getElement('attribute_value', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode]); + + match ($attributeValue->getTagName()) { + 'input' => $attributeValue->setValue($value), + 'select' => $attributeValue->selectOption($value), + default => throw new \InvalidArgumentException('Unsupported attribute value type'), + }; + + $attributeValue->blur(); + $this->waitForFormUpdate(); + } + + public function removeAttribute(string $attributeName, string $localeCode): void + { + $this->changeTab('attributes'); + + $this->getElement('product_attribute_delete_button', ['%attributeName%' => $attributeName])->press(); + + $this->waitForFormUpdate(); + } + + public function getAttributeValue(string $attribute, string $localeCode): string + { + $this->changeTab('attributes'); + $this->changeAttributeTab($attribute); + + $attributeValue = $this->getElement('attribute_value', ['%attributeName%' => $attribute, '%localeCode%' => $localeCode]); + + return match ($attributeValue->getTagName()) { + 'input' => $attributeValue->getValue(), + 'select' => $attributeValue->getText(), + default => throw new \InvalidArgumentException('Unsupported attribute value type'), + }; + } + + public function addSelectedAttributes(): void + { + $this->changeTab('attributes'); + $this->clickButton('Add'); + $this->waitForFormUpdate(); + } + + public function getNumberOfAttributes(): int + { + return count($this->getDocument()->findAll('css', '[data-test-product-attribute-tab]')); + } + + private function selectAttributeToBeAdded(string $attributeName): void + { + $driver = $this->getDriver(); + $this->autocompleteHelper->selectByName( + $driver, + $this->getElement('product_attribute_input')->getXpath(), + $attributeName, + ); + } + + /* + * Associations management + */ + + public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void + { + $this->changeTab('associations'); + $associationField = $this->getElement('field_associations', ['%association%' => $productAssociationType->getCode()]); + + foreach ($productsNames as $productName) { + $this->autocompleteHelper->selectByName( + $this->getDriver(), + $associationField->getXpath(), + $productName, + ); + $this->waitForFormUpdate(); + } + } + + public function removeAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): void + { + $this->changeTab('associations'); + $associationField = $this->getElement('field_associations', ['%association%' => $productAssociationType->getCode()]); + + $this->autocompleteHelper->removeByValue( + $this->getDriver(), + $associationField->getXpath(), + $product->getCode(), + ); + } + + public function hasAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): bool + { + $this->changeTab('associations'); + $associationField = $this->getElement('field_associations', ['%association%' => $productAssociationType->getCode()]); + + return in_array($product->getCode(), $associationField->getValue(), true); + } + + /* + * Media management + */ + + public function attachImage(string $path, ?string $type = null, ?ProductVariantInterface $productVariant = null): void + { + $this->changeTab('media'); + $this->clickButton('Add image'); + $this->waitForFormUpdate(); + + $images = $this->getElement('images'); + $imagesSubform = $images->findAll('css', '[data-test-image-subform]'); + $imageSubform = end($imagesSubform); + + if (null !== $type) { + $imageSubform->fillField('Type', $type); + } + + if (null !== $productVariant) { + $this->autocompleteHelper->selectByValue( + $this->getDriver(), + $imageSubform->find('css', '[data-test-product-variant]')->getXpath(), + $productVariant->getCode(), + ); + } + + $filesPath = $this->getParameter('files_path'); + $imageSubform->find('css', '[data-test-file]')->attachFile($filesPath . $path); + } + + public function changeImageWithType(string $type, string $path): void + { + $filesPath = $this->getParameter('files_path'); + + $imageSubform = $this->getElement('image_subform_with_type', ['%type%' => $type]); + $imageSubform->find('css', '[data-test-file]')->attachFile($filesPath . $path); + } + + public function removeImageWithType(string $type): void + { + $this->changeTab('media'); + + $imageSubform = $this->getElement('image_subform_with_type', ['%type%' => $type]); + $imageSubform->find('css', '[data-test-image-delete]')->click(); + $this->waitForFormUpdate(); + } + + public function removeFirstImage(): void + { + $this->changeTab('media'); + $firstSubform = $this->getFirstImageSubform(); + $firstSubform->findAll('css', '[data-test-image-delete]')[0]->click(); + } + + public function hasImageWithType(string $type): bool + { + $this->changeTab('media'); + + try { + $imageSubform = $this->getElement('image_subform_with_type', ['%type%' => $type]); + } catch (ElementNotFoundException) { + return false; + } + + $imageUrl = $imageSubform->getAttribute('data-test-image-url'); + $this->getDriver()->visit($imageUrl); + $statusCode = $this->getDriver()->getStatusCode(); + $this->getDriver()->back(); + + return in_array($statusCode, [200, 304], true); + } + + public function hasImageWithVariant(ProductVariantInterface $productVariant): bool + { + $this->changeTab('media'); + $images = $this->getElement('images'); + + return $images->has('css', sprintf('[data-test-product-variant="%s"]', $productVariant->getCode())); + } + + public function countImages(): int + { + $images = $this->getElement('images'); + $imageSubforms = $images->findAll('css', '[data-test-image-subform]'); + + return count($imageSubforms); + } + + public function modifyFirstImageType(string $type): void + { + $this->changeTab('media'); + + $firstImageSubform = $this->getFirstImageSubform(); + + $firstImageSubform->find('css', 'input[data-test-type]')->setValue($type); + } + + public function selectVariantForFirstImage(ProductVariantInterface $productVariant): void + { + $this->changeTab('media'); + + $imageSubform = $this->getFirstImageSubform(); + $this->autocompleteHelper->selectByValue( + $this->getDriver(), + $imageSubform->find('css', '[data-test-product-variant]')->getXpath(), + $productVariant->getCode(), + ); + } + + private function getFirstImageSubform(): NodeElement + { + $images = $this->getElement('images'); + $imageSubforms = $images->findAll('css', '[data-test-image-subform]'); + + return reset($imageSubforms); + } + + /* + * Helpers + */ + + private function waitForFormUpdate(): void + { + $form = $this->getElement('form'); + sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute + $form->waitFor(1500, function () use ($form) { + return !$form->hasAttribute('busy'); + }); + } + + private function clickButton(string $locator): void + { + $this->getDocument()->pressButton($locator); + } +} diff --git a/src/Sylius/Behat/Page/Admin/Product/IndexPage.php b/src/Sylius/Behat/Page/Admin/Product/IndexPage.php index 661b8b5dc8..e1cd4625c7 100644 --- a/src/Sylius/Behat/Page/Admin/Product/IndexPage.php +++ b/src/Sylius/Behat/Page/Admin/Product/IndexPage.php @@ -61,7 +61,7 @@ class IndexPage extends CrudIndexPage implements IndexPageInterface $table = $this->getElement('table'); $row = $tableAccessor->getRowWithFields($table, ['name' => $productName]); $field = $tableAccessor->getFieldFromRow($table, $row, 'actions'); - $field->clickLink('Details'); + $field->clickLink('details'); } public function goToPage(int $page): void diff --git a/src/Sylius/Behat/Page/Admin/Product/ShowPage.php b/src/Sylius/Behat/Page/Admin/Product/ShowPage.php index d5bb4aa31d..8b91764bd7 100644 --- a/src/Sylius/Behat/Page/Admin/Product/ShowPage.php +++ b/src/Sylius/Behat/Page/Admin/Product/ShowPage.php @@ -26,7 +26,7 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function isShowInShopButtonDisabled(): bool { - return $this->getElement('show_product_single_button')->hasClass('disabled'); + return $this->getElement('show_product_button')->hasClass('disabled'); } public function getAppliedCatalogPromotionsLinks(string $variantName, string $channelName): array @@ -60,12 +60,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface public function showProductInChannel(string $channel): void { - $this->getElement('show_product_dropdown')->clickLink($channel); + $this->getElement('show_product_button')->clickLink($channel); } public function showProductInSingleChannel(): void { - $this->getElement('show_product_single_button')->click(); + $this->getElement('show_product_button')->click(); } public function showProductEditPage(): void @@ -81,13 +81,12 @@ class ShowPage extends SymfonyPage implements ShowPageInterface protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ + 'breadcrumb' => '.breadcrumb > div', 'edit_product_button' => '#edit-product', 'edit_variant_button' => '#variants .variants-accordion__title:contains("%variantCode%") .edit-variant', 'product_name' => '#header h1 .content > span', - 'show_product_dropdown' => '.scrolling.menu', - 'show_product_single_button' => '.ui.labeled.icon.button', + 'show_product_button' => '[data-test-view-in-store]', 'variants' => '#variants', - 'breadcrumb' => '.breadcrumb > div', ]); } diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php index 87c17ebad2..cb2f439adb 100644 --- a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php +++ b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPage.php @@ -14,25 +14,38 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Product; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; use Sylius\Behat\Behaviour\ChecksCodeImmutability; use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage; use Sylius\Behat\Service\AutocompleteHelper; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Component\Core\Model\ProductVariantInterface; use Sylius\Component\Taxonomy\Model\TaxonInterface; +use Symfony\Component\Routing\RouterInterface; use Webmozart\Assert\Assert; class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConfigurableProductPageInterface { use ChecksCodeImmutability; + use FormTrait; + + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + string $routeName, + private AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $routeName); + } private array $imageUrls = []; - public function nameItIn(string $name, string $localeCode): void + public function saveChanges(): void { - $this->getDocument()->fillField( - sprintf('sylius_product_translations_%s_name', $localeCode), - $name, - ); + $this->waitForFormUpdate(); + + parent::saveChanges(); } public function setMetaKeywords(string $keywords, string $localeCode): void @@ -105,91 +118,7 @@ class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConf public function hasLastImageAVariant(ProductVariantInterface $productVariant): bool { - $this->clickTabIfItsNotActive('media'); - - $imageForm = $this->getLastImageElement(); - - return $productVariant->getCode() === $imageForm->find('css', 'input[type="hidden"]')->getValue(); - } - - public function attachImage(string $path, ?string $type = null, ?ProductVariantInterface $productVariant = null): void - { - $this->clickTabIfItsNotActive('media'); - $this->getDocument()->clickLink('Add'); - - $imageForm = $this->getLastImageElement(); - - if (null !== $type) { - $imageForm->fillField('Type', $type); - } - - if (null !== $productVariant) { - $imageForm->find('css', 'input[type="hidden"]')->setValue($productVariant->getCode()); - } - - $filesPath = $this->getParameter('files_path'); - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function changeImageWithType(string $type, string $path): void - { - $filesPath = $this->getParameter('files_path'); - - $imageForm = $this->getImageElementByType($type); - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function removeImageWithType(string $type): void - { - $this->clickTabIfItsNotActive('media'); - - $imageElement = $this->getImageElementByType($type); - $imageSourceElement = $imageElement->find('css', 'img'); - if (null !== $imageSourceElement) { - $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src')); - } - - $imageElement->clickLink('Delete'); - } - - public function removeFirstImage(): void - { - $this->clickTabIfItsNotActive('media'); - $imageElement = $this->getFirstImageElement(); - $imageTypeElement = $imageElement->find('css', 'input[type=text]'); - $imageSourceElement = $imageElement->find('css', 'img'); - - if (null !== $imageTypeElement && null !== $imageSourceElement) { - $this->saveImageUrlForType( - $imageTypeElement->getValue(), - $imageSourceElement->getAttribute('src'), - ); - } - - $imageElement->clickLink('Delete'); - } - - public function modifyFirstImageType(string $type): void - { - $this->clickTabIfItsNotActive('media'); - - $firstImage = $this->getFirstImageElement(); - $this->setImageType($firstImage, $type); - } - - public function selectVariantForFirstImage(ProductVariantInterface $productVariant): void - { - $this->clickTabIfItsNotActive('media'); - - $imageElement = $this->getFirstImageElement(); - $imageElement->find('css', 'input[type="hidden"]')->setValue($productVariant->getCode()); - } - - public function countImages(): int - { - $imageElements = $this->getImageElements(); - - return count($imageElements); + return $this->hasImageWithVariant($productVariant); } public function goToVariantsList(): void @@ -207,11 +136,6 @@ class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConf $this->getDocument()->clickLink('Generate'); } - public function hasInventoryTab(): bool - { - return null !== $this->getDocument()->find('css', '.tab > h3:contains("Inventory")'); - } - protected function getCodeElement(): NodeElement { return $this->getElement('code'); @@ -219,20 +143,24 @@ class UpdateConfigurableProductPage extends BaseUpdatePage implements UpdateConf protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'channel_checkbox' => '.checkbox:contains("%channel%") input', - 'channels' => '#sylius_product_channels', - 'code' => '#sylius_product_code', - 'images' => '#sylius_product_images', - 'main_taxon' => '#sylius_product_mainTaxon', - 'name' => '#sylius_product_translations_en_US_name', - 'options' => '#sylius_product_options', - 'price' => '#sylius_product_variant_price', - 'search' => '.ui.fluid.search.selection.dropdown', - 'search_item_selected' => 'div.menu > div.item.selected', - 'tab' => '.menu [data-tab="%name%"]', - 'taxonomy' => 'a[data-tab="taxonomy"]', - ]); + return array_merge( + parent::getDefinedElements(), + [ + 'channel_checkbox' => '.checkbox:contains("%channel%") input', + 'channels' => '#sylius_product_channels', + 'code' => '#sylius_product_code', + 'images' => '#sylius_product_images', + 'main_taxon' => '#sylius_product_mainTaxon', + 'name' => '#sylius_product_translations_en_US_name', + 'options' => '#sylius_product_options', + 'price' => '#sylius_product_variant_price', + 'search' => '.ui.fluid.search.selection.dropdown', + 'search_item_selected' => 'div.menu > div.item.selected', + 'tab' => '.menu [data-tab="%name%"]', + 'taxonomy' => 'a[data-tab="taxonomy"]', + ], + $this->getDefinedFormElements(), + ); } private function openTaxonBookmarks(): void diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php index 33deb9c193..9075890e36 100644 --- a/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Product/UpdateConfigurableProductPageInterface.php @@ -41,6 +41,8 @@ interface UpdateConfigurableProductPageInterface extends UpdatePageInterface public function hasLastImageAVariant(ProductVariantInterface $productVariant): bool; + public function hasImageWithType(string $type): bool; + public function attachImage(string $path, ?string $type = null, ?ProductVariantInterface $productVariant = null): void; public function changeImageWithType(string $type, string $path): void; @@ -61,5 +63,5 @@ interface UpdateConfigurableProductPageInterface extends UpdatePageInterface public function goToVariantGeneration(): void; - public function hasInventoryTab(): bool; + public function hasTab(string $name): bool; } diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php index 96c5b526e5..d275d8c286 100644 --- a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php +++ b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPage.php @@ -14,34 +14,41 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Product; use Behat\Mink\Element\NodeElement; +use Behat\Mink\Session; use Sylius\Behat\Behaviour\ChecksCodeImmutability; use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage; use Sylius\Behat\Service\AutocompleteHelper; use Sylius\Behat\Service\DriverHelper; +use Sylius\Behat\Service\Helper\AutocompleteHelperInterface; use Sylius\Behat\Service\SlugGenerationHelper; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\TaxonInterface; use Sylius\Component\Currency\Model\CurrencyInterface; -use Sylius\Component\Product\Model\ProductAssociationTypeInterface; +use Symfony\Component\Routing\RouterInterface; use Webmozart\Assert\Assert; class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProductPageInterface { use ChecksCodeImmutability; + use FormTrait; + + public function __construct( + Session $session, + $minkParameters, + RouterInterface $router, + string $routeName, + private readonly AutocompleteHelperInterface $autocompleteHelper, + ) { + parent::__construct($session, $minkParameters, $router, $routeName); + } private array $imageUrls = []; - public function nameItIn(string $name, string $localeCode): void + public function saveChanges(): void { - $this->activateLanguageTab($localeCode); - $this->getElement('name', ['%locale%' => $localeCode])->setValue($name); + $this->waitForFormUpdate(); - if (DriverHelper::isJavascript($this->getDriver())) { - SlugGenerationHelper::waitForSlugGeneration( - $this->getSession(), - $this->getElement('slug', ['%locale%' => $localeCode]), - ); - } + parent::saveChanges(); } public function specifyPrice(ChannelInterface $channel, string $price): void @@ -54,16 +61,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->setValue($originalPrice); } - public function addSelectedAttributes(): void - { - $this->clickTabIfItsNotActive('attributes'); - $this->getDocument()->pressButton('Add attributes'); - - $form = $this->getDocument()->find('css', 'form'); - - $this->getDocument()->waitFor(1, fn () => $form->hasClass('loading')); - } - public function removeAttribute(string $attributeName, string $localeCode): void { $this->clickTabIfItsNotActive('attributes'); @@ -71,13 +68,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd $this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '$localeCode%' => $localeCode])->press(); } - public function getAttributeValue(string $attribute, string $localeCode): string - { - $this->clickTabIfItsNotActive('attributes'); - - return $this->getElement('attribute', ['%attributeName%' => $attribute, '%localeCode%' => $localeCode])->getValue(); - } - public function getAttributeSelectText(string $attribute, string $localeCode): string { $this->clickTabIfItsNotActive('attributes'); @@ -101,11 +91,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd return $validationError->getText(); } - public function getNumberOfAttributes(): int - { - return count($this->getDocument()->findAll('css', '.attribute')); - } - public function hasAttribute(string $attributeName): bool { return null !== $this->getDocument()->find('css', sprintf('.attribute .label:contains("%s")', $attributeName)); @@ -230,74 +215,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd return in_array($statusCode, [200, 304], true); } - public function attachImage(string $path, ?string $type = null): void - { - $this->clickTabIfItsNotActive('media'); - - $filesPath = $this->getParameter('files_path'); - - $this->getDocument()->clickLink('Add'); - - $imageForm = $this->getLastImageElement(); - if (null !== $type) { - $imageForm->fillField('Type', $type); - } - - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function changeImageWithType(string $type, string $path): void - { - $filesPath = $this->getParameter('files_path'); - - $imageForm = $this->getImageElementByType($type); - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function removeImageWithType(string $type): void - { - $this->clickTabIfItsNotActive('media'); - - $imageElement = $this->getImageElementByType($type); - $imageSourceElement = $imageElement->find('css', 'img'); - if (null !== $imageSourceElement) { - $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src')); - } - - $imageElement->clickLink('Delete'); - } - - public function removeFirstImage(): void - { - $this->clickTabIfItsNotActive('media'); - $imageElement = $this->getFirstImageElement(); - $imageTypeElement = $imageElement->find('css', 'input[type=text]'); - $imageSourceElement = $imageElement->find('css', 'img'); - - if (null !== $imageTypeElement && null !== $imageSourceElement) { - $this->saveImageUrlForType( - $imageTypeElement->getValue(), - $imageSourceElement->getAttribute('src'), - ); - } - $imageElement->clickLink('Delete'); - } - - public function modifyFirstImageType(string $type): void - { - $this->clickTabIfItsNotActive('media'); - - $firstImage = $this->getFirstImageElement(); - $this->setImageType($firstImage, $type); - } - - public function countImages(): int - { - $imageElements = $this->getImageElements(); - - return count($imageElements); - } - public function isSlugReadonlyIn(string $locale): bool { return SlugGenerationHelper::isSlugReadonly( @@ -306,53 +223,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd ); } - public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void - { - $this->clickTab('associations'); - - $dropdown = $this->getElement('association_dropdown', [ - '%association%' => $productAssociationType->getName(), - ]); - $dropdown->click(); - - foreach ($productsNames as $productName) { - $dropdown->waitFor(5, fn () => $this->hasElement('association_dropdown_item', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ])); - - $item = $this->getElement('association_dropdown_item', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ]); - $item->click(); - } - } - - public function hasAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): bool - { - $this->clickTabIfItsNotActive('associations'); - - return $this->hasElement('association_dropdown_item', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ]); - } - - public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void - { - $this->clickTabIfItsNotActive('associations'); - - $item = $this->getElement('association_dropdown_item_selected', [ - '%association%' => $productAssociationType->getName(), - '%item%' => $productName, - ]); - - $deleteIcon = $item->find('css', 'i.delete'); - Assert::notNull($deleteIcon); - $deleteIcon->click(); - } - public function getPricingConfigurationForChannelAndCurrencyCalculator(ChannelInterface $channel, CurrencyInterface $currency): string { $priceConfigurationElement = $this->getElement('pricing_configuration'); @@ -398,11 +268,6 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd return $this->getElement('original_price', ['%channelCode%' => $channel->getCode()])->getValue(); } - public function isShippingRequired(): bool - { - return $this->getElement('shipping_required')->isChecked(); - } - public function goToVariantsList(): void { $this->getDocument()->clickLink('List variants'); @@ -418,29 +283,24 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd $this->getDocument()->clickLink('Generate'); } - public function hasInventoryTab(): bool - { - return null !== $this->getDocument()->find('css', '.tab > h3:contains("Inventory")'); - } - public function getShowProductInSingleChannelUrl(): string { - return $this->getElement('show_product_single_button')->getAttribute('href'); + return $this->getElement('show_product_button')->getAttribute('href'); } public function isShowInShopButtonDisabled(): bool { - return $this->getElement('show_product_single_button')->hasClass('disabled'); + return $this->getElement('show_product_button')->hasClass('disabled'); } public function showProductInChannel(string $channel): void { - $this->getElement('show_product_dropdown')->clickLink($channel); + $this->getElement('show_product_button')->clickLink($channel); } public function showProductInSingleChannel(): void { - $this->getElement('show_product_single_button')->click(); + $this->getElement('show_product_button')->click(); } public function disable(): void @@ -479,39 +339,42 @@ class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProd protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select', - 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")', - 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")', - 'attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input', - 'attribute_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select', - 'attribute_element' => '.attribute', - 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button', - 'code' => '#sylius_product_code', - 'images' => '#sylius_product_images', - 'language_tab' => '[data-locale="%locale%"] .title', - 'locale_tab' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"]', - 'name' => '#sylius_product_translations_%locale%_name', - 'prices' => '#sylius_product_variant_channelPricings', - 'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]', - 'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]', - 'pricing_configuration' => '#sylius_calculator_container', - 'main_taxon' => '#sylius_product_mainTaxon', - 'meta_description' => '#sylius_product_translations_%locale%_metaDescription', - 'meta_keywords' => '#sylius_product_translations_%locale%_metaKeywords', - 'non_translatable_attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input', - 'product_taxon' => '#sylius-product-taxonomy-tree .item .header:contains("%taxonName%") input', - 'product_taxons' => '#sylius_product_productTaxons', - 'shipping_required' => '#sylius_product_variant_shippingRequired', - 'show_product_dropdown' => '.scrolling.menu', - 'show_product_single_button' => '[data-test-show-product-in-shop-page]', - 'slug' => '#sylius_product_translations_%locale%_slug', - 'tab' => '.menu [data-tab="%name%"]', - 'taxonomy' => 'a[data-tab="taxonomy"]', - 'tracked' => '#sylius_product_variant_tracked', - 'toggle_slug_modification_button' => '[data-locale="%locale%"] .toggle-product-slug-modification', - 'enabled' => '#sylius_product_enabled', - ]); + return array_merge( + parent::getDefinedElements(), + [ + 'association_dropdown' => '.field > label:contains("%association%") ~ .product-select', + 'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")', + 'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")', + 'attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] input', + 'attribute_select' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"] select', + 'attribute_element' => '.attribute', + 'attribute_delete_button' => '#attributesContainer .attributes-group .attributes-header:contains("%attributeName%") button', + 'code' => '#sylius_product_code', + 'images' => '#sylius_product_images', + 'language_tab' => '[data-locale="%locale%"] .title', + 'locale_tab' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% %localeCode%"]', + 'name' => '#sylius_product_translations_%locale%_name', + 'prices' => '#sylius_product_variant_channelPricings', + 'original_price' => '#sylius_product_variant_channelPricings input[name$="[originalPrice]"][id*="%channelCode%"]', + 'price' => '#sylius_product_variant_channelPricings input[id*="%channelCode%"]', + 'pricing_configuration' => '#sylius_calculator_container', + 'main_taxon' => '#sylius_product_mainTaxon', + 'meta_description' => '#sylius_product_translations_%locale%_metaDescription', + 'meta_keywords' => '#sylius_product_translations_%locale%_metaKeywords', + 'non_translatable_attribute' => '#attributesContainer [data-test-product-attribute-value-in-locale="%attributeName% "] input', + 'product_taxon' => '#sylius-product-taxonomy-tree .item .header:contains("%taxonName%") input', + 'product_taxons' => '#sylius_product_productTaxons', + 'shipping_required' => '#sylius_product_variant_shippingRequired', + 'show_product_button' => '[data-test-view-in-store]', + 'slug' => '#sylius_product_translations_%locale%_slug', + 'tab' => '.menu [data-tab="%name%"]', + 'taxonomy' => 'a[data-tab="taxonomy"]', + 'tracked' => '#sylius_product_variant_tracked', + 'toggle_slug_modification_button' => '[data-locale="%locale%"] .toggle-product-slug-modification', + 'enabled' => '#sylius_product_enabled', + ], + $this->getDefinedFormElements(), + ); } private function openTaxonBookmarks(): void diff --git a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php index aebe8fd92f..6e61960919 100644 --- a/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Product/UpdateSimpleProductPageInterface.php @@ -15,6 +15,7 @@ namespace Sylius\Behat\Page\Admin\Product; use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Core\Model\ProductInterface; use Sylius\Component\Core\Model\TaxonInterface; use Sylius\Component\Currency\Model\CurrencyInterface; use Sylius\Component\Product\Model\ProductAssociationTypeInterface; @@ -71,6 +72,8 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface public function isImageWithTypeDisplayed(string $type): bool; + public function hasImageWithType(string $type): bool; + public function attachImage(string $path, ?string $type = null): void; public function changeImageWithType(string $type, string $path): void; @@ -88,9 +91,9 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface */ public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void; - public function hasAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): bool; + public function hasAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): bool; - public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void; + public function removeAssociatedProduct(ProductInterface $product, ProductAssociationTypeInterface $productAssociationType): void; public function getPricingConfigurationForChannelAndCurrencyCalculator(ChannelInterface $channel, CurrencyInterface $currency): string; @@ -112,7 +115,7 @@ interface UpdateSimpleProductPageInterface extends BaseUpdatePageInterface public function goToVariantGeneration(): void; - public function hasInventoryTab(): bool; + public function hasTab(string $name): bool; public function getShowProductInSingleChannelUrl(): string; diff --git a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePage.php b/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePage.php deleted file mode 100644 index 699e3f5f1b..0000000000 --- a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePage.php +++ /dev/null @@ -1,44 +0,0 @@ -getDocument()->fillField( - sprintf('sylius_product_association_type_translations_%s_name', $language), - $name, - ); - } - - protected function getCodeElement(): NodeElement - { - return $this->getElement('code'); - } - - protected function getDefinedElements(): array - { - return array_merge(parent::getDefinedElements(), [ - 'code' => '#sylius_product_association_type_code', - 'name' => '#sylius_product_association_type_translations_en_US_name', - ]); - } -} diff --git a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePageInterface.php deleted file mode 100644 index 5942b52349..0000000000 --- a/src/Sylius/Behat/Page/Admin/ProductAssociationType/CreatePageInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -getDocument()->fillField( - sprintf('sylius_product_association_type_translations_%s_name', $language), - $name, - ); - } - - public function nameIt($name): void - { - $this->getElement('name')->setValue($name); - } - - protected function getCodeElement(): NodeElement - { - return $this->getElement('code'); - } - - protected function getDefinedElements(): array - { - return array_merge(parent::getDefinedElements(), [ - 'code' => '#sylius_product_association_type_code', - 'name' => '#sylius_product_association_type_translations_en_US_name', - ]); - } -} diff --git a/src/Sylius/Behat/Page/Admin/ProductAssociationType/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/ProductAssociationType/UpdatePageInterface.php deleted file mode 100644 index f073d45076..0000000000 --- a/src/Sylius/Behat/Page/Admin/ProductAssociationType/UpdatePageInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -getDocument()->find('css', 'form[name="sylius_product_variant"]'); - if (null === $formElement) { - throw new ElementNotFoundException($this->getSession(), 'Field element'); - } + $validationMessage = $this->getDocument()->find('css', '.alert.alert-danger.d-block'); - $validationMessage = $formElement->find('css', '.sylius-validation-error'); if (null === $validationMessage) { - throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.alert.alert-danger.d-block'); } return $validationMessage->getText(); @@ -91,7 +87,7 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface public function getPricesValidationMessage(): string { - return $this->getElement('prices_validation_message')->getText(); + return $this->getElement('prices-body')->getText(); } public function setShippingRequired(bool $isShippingRequired): void @@ -120,7 +116,7 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface 'shipping_required' => '#sylius_product_variant_shippingRequired', 'original_price' => '#sylius_product_variant_channelPricings_%channelCode%_originalPrice', 'price' => '#sylius_product_variant_channelPricings_%channelCode%_price', - 'prices_validation_message' => '#sylius_product_variant_channelPricings ~ .sylius-validation-error, #sylius_product_variant_channelPricings .sylius-validation-error', + 'prices-body' => '[data-test-product-channel-pricings-accordion-body]', 'weight' => '#sylius_product_variant_weight', 'width' => '#sylius_product_variant_width', ]); diff --git a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php index b541d5dd88..344d7575fb 100644 --- a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php +++ b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePage.php @@ -16,78 +16,95 @@ namespace Sylius\Behat\Page\Admin\ProductVariant; use Behat\Mink\Element\NodeElement; use Behat\Mink\Exception\ElementNotFoundException; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage; -use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Behat\Service\TabsHelper; class GeneratePage extends SymfonyPage implements GeneratePageInterface { - public function generate(): void - { - $this->getDocument()->pressButton('Generate'); - } - - public function specifyPrice(int $nth, int $price, ChannelInterface $channel): void - { - $this->getElement('price', ['%position%' => $nth, '%channelCode%' => $channel->getCode()])->setValue($price); - } - - public function specifyCode(int $nth, string $code): void - { - $this->getDocument()->fillField(sprintf('sylius_product_generate_variants_variants_%s_code', $nth), $code); - } - - public function removeVariant(int $nth): void - { - $item = $this->getDocument()->find('css', sprintf('div[data-form-collection-index="%s"]', $nth)); - - $item->clickLink('Delete'); - } - public function getRouteName(): string { return 'sylius_admin_product_variant_generate'; } - /** - * @throws ElementNotFoundException - */ - public function getValidationMessage(string $element, int $position): string + public function specifyCode(int $nth, string $code): void { - $foundElement = $this->getElement($element, ['%position%' => $position]); - $validatedField = $this->getValidatedField($foundElement); - - return $validatedField->find('css', '.sylius-validation-error')->getText(); + $this->getElement('code', ['%position%' => $nth])->setValue($code); } - public function getPricesValidationMessage(int $position): string + public function specifyPrice(int $nth, int $price, string $channelCode): void { - return $this->getElement('prices_validation_message', ['%position%' => $position])->getText(); + $channelPricing = $this->getElement('channel_pricings', ['%position%' => $nth]); + + TabsHelper::switchTab($this->getSession(), $channelPricing, $channelCode); + + $channelPricing->find('css', sprintf('[id$="_channelPricings_%s"]', $channelCode))->fillField('Price', $price); + } + + public function generate(): void + { + $this->getElement('generate_button')->press(); + } + + public function removeVariant(int $nth): void + { + $this->getElement('delete_button', ['%position%' => $nth])->click(); + $this->waitForFormUpdate(); + } + + public function getValidationMessage(string $element, int $position): string + { + $foundElement = $this->getFieldElement($element, ['%position%' => $position]); + if (null === $foundElement) { + throw new ElementNotFoundException($this->getSession(), 'Field element'); + } + + $validationMessage = $foundElement->find('css', '.invalid-feedback'); + if (null === $validationMessage) { + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); + } + + return $validationMessage->getText(); + } + + public function isGenerationPossible(): bool + { + return !$this->getElement('generate_button')->hasAttribute('disabled'); + } + + public function isProductVariantRemovable(int $nth): bool + { + return $this->hasElement('delete_button', ['%position%' => $nth]); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'code' => '#sylius_product_generate_variants_variants_%position%_code', - 'price' => '#sylius_product_generate_variants_variants_%position%_channelPricings_%channelCode% input[id*="%channelCode%"]', - 'prices_validation_message' => 'div[data-form-collection-index="%position%"] div.tabular.menu ~ .sylius-validation-error', + 'generate_button' => '[data-test-generate-button]', + 'delete_button' => '#sylius_product_generate_variants_variants_%position% [data-test-delete-button]', + 'code' => '#sylius_product_generate_variants_variants_%position% [data-test-code]', + 'channel_pricings' => '#sylius_product_generate_variants_variants_%position% [data-test-channel-pricings]', + 'form' => '[data-live-name-value="sylius_admin:product:generate_product_variants_form"]', ]); } + private function waitForFormUpdate(): void + { + $form = $this->getElement('form'); + sleep(1); // we need to sleep, as sometimes the check below is executed faster than the form sets the busy attribute + $form->waitFor(1500, function () use ($form) { + return !$form->hasAttribute('busy'); + }); + } + /** * @throws ElementNotFoundException */ - private function getValidatedField(NodeElement $element): NodeElement + private function getFieldElement(string $element, array $parameters = []): ?NodeElement { + $element = $this->getElement($element, $parameters); while (null !== $element && !$element->hasClass('field')) { $element = $element->getParent(); } return $element; } - - public function isGenerationPossible(): bool - { - $generateButton = $this->getDocument()->find('css', 'button:contains("Generate")'); - - return !$generateButton->hasAttribute('disabled'); - } } diff --git a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php index 3bce79d52d..2bc9fa72c1 100644 --- a/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/ProductVariant/GeneratePageInterface.php @@ -14,13 +14,12 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ProductVariant; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPageInterface; -use Sylius\Component\Core\Model\ChannelInterface; interface GeneratePageInterface extends SymfonyPageInterface { public function generate(): void; - public function specifyPrice(int $nth, int $price, ChannelInterface $channel): void; + public function specifyPrice(int $nth, int $price, string $channelCode): void; public function specifyCode(int $nth, string $code): void; @@ -28,7 +27,7 @@ interface GeneratePageInterface extends SymfonyPageInterface public function getValidationMessage(string $element, int $position): string; - public function getPricesValidationMessage(int $position): string; - public function isGenerationPossible(): bool; + + public function isProductVariantRemovable(int $nth): bool; } diff --git a/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php b/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php index 90643c6ddf..666ab50e5d 100644 --- a/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php +++ b/src/Sylius/Behat/Page/Admin/ProductVariant/IndexPage.php @@ -55,15 +55,15 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface public function countItemsWithNoName(): int { - return count($this->getElement('table')->findAll('css', '[data-test-missing-translation-paragraph]')); + return count($this->getElement('table')->findAll('css', '[data-test-missing-translation]')); } protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'on_hand_quantity' => '.onHand[data-product-variant-id="%id%"]', - 'on_hold_quantity' => '.onHold[data-product-variant-id="%id%"]', - 'save_configuration_button' => '.sylius-save-position', + 'on_hand_quantity' => '[data-test-on-hand][data-product-variant-id="%id%"]', + 'on_hold_quantity' => '[data-test-on-hold][data-product-variant-id="%id%"]', + 'save_configuration_button' => '[data-test-save-configuration-button]', ]); } } diff --git a/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php b/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php index 7347b83199..4c735f2970 100644 --- a/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/Promotion/CreatePage.php @@ -18,249 +18,44 @@ use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Behaviour\NamesIt; use Sylius\Behat\Behaviour\SpecifiesItsField; use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; -use Sylius\Behat\Service\AutocompleteHelper; -use Sylius\Behat\Service\TabsHelper; -use Webmozart\Assert\Assert; class CreatePage extends BaseCreatePage implements CreatePageInterface { use NamesIt; use SpecifiesItsField; - public function specifyLabel(string $label, string $localeCode): void + public function getValidationMessage(string $element): string { - $this->getDocument()->find('css', 'div[data-locale="' . $localeCode . '"]')->click(); - - $this->getDocument()->fillField(sprintf('sylius_promotion_translations_%s_label', $localeCode), $label); - } - - public function addRule(?string $ruleName): void - { - $count = count($this->getCollectionItems('rules')); - - $this->getDocument()->clickLink('Add rule'); - - $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('rules'))); - - if (null !== $ruleName) { - $this->selectRuleOption('Type', $ruleName); - } - } - - public function selectRuleOption(string $option, string $value, bool $multiple = false): void - { - $this->getLastCollectionItem('rules')->find('named', ['select', $option])->selectOption($value, $multiple); - } - - public function selectAutocompleteRuleOption(string $option, $value, bool $multiple = false): void - { - $option = strtolower(str_replace(' ', '_', $option)); - - $ruleAutocomplete = $this - ->getLastCollectionItem('rules') - ->find('css', sprintf('input[type="hidden"][name*="[%s]"]', $option)) - ->getParent() - ; - - if ($multiple && is_array($value)) { - AutocompleteHelper::chooseValues($this->getSession(), $ruleAutocomplete, $value); - - return; - } - - AutocompleteHelper::chooseValue($this->getSession(), $ruleAutocomplete, $value); - } - - public function fillRuleOption(string $option, string $value): void - { - $this->getLastCollectionItem('rules')->fillField($option, $value); - } - - public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void - { - $lastAction = $this->getChannelConfigurationOfLastRule($channelCode); - $lastAction->fillField($option, $value); - } - - public function addAction(?string $actionName): void - { - $count = count($this->getCollectionItems('actions')); - - $this->getDocument()->clickLink('Add action'); - - $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('actions'))); - - if (null !== $actionName) { - $this->selectActionOption('Type', $actionName); - } - } - - public function selectActionOption(string $option, string $value, bool $multiple = false): void - { - $this->getLastCollectionItem('actions')->find('named', ['select', $option])->selectOption($value, $multiple); - } - - public function fillActionOption(string $option, string $value): void - { - $this->getLastCollectionItem('actions')->fillField($option, $value); - } - - public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void - { - $lastAction = $this->getChannelConfigurationOfLastAction($channelCode); - $lastAction->fillField($option, $value); - } - - public function fillUsageLimit(string $limit): void - { - $this->getDocument()->fillField('Usage limit', $limit); - } - - public function makeExclusive(): void - { - $this->getDocument()->checkField('Exclusive'); - } - - public function makeNotAppliesToDiscountedItem(): void - { - $this->getDocument()->unCheckField('Applies to already discounted order items'); - } - - public function checkCouponBased(): void - { - $this->getDocument()->checkField('Coupon based'); - } - - public function checkChannel(string $name): void - { - $this->getDocument()->checkField($name); - } - - public function setStartsAt(\DateTimeInterface $dateTime): void - { - $timestamp = $dateTime->getTimestamp(); - - $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp)); - $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp)); - } - - public function setEndsAt(\DateTimeInterface $dateTime): void - { - $timestamp = $dateTime->getTimestamp(); - - $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp)); - $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp)); - } - - public function getValidationMessageForAction(): string - { - $actionForm = $this->getLastCollectionItem('actions'); - - $foundElement = $actionForm->find('css', '.sylius-validation-error'); + $foundElement = $this->getFieldElement($element); if (null === $foundElement) { - throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error'); + throw new ElementNotFoundException($this->getSession(), 'Field element'); } - return $foundElement->getText(); - } - - public function selectAutoCompleteFilterOption(string $option, $value, bool $multiple = false): void - { - $option = strtolower(str_replace(' ', '_', $option)); - - $filterAutocomplete = $this - ->getLastCollectionItem('actions') - ->find('css', sprintf('input[type="hidden"][name*="[%s_filter]"]', $option)) - ->getParent() - ; - - if ($multiple && is_array($value)) { - AutocompleteHelper::chooseValues($this->getSession(), $filterAutocomplete, $value); - - return; + $validationMessage = $foundElement->find('css', '.invalid-feedback'); + if (null === $validationMessage) { + throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.invalid-feedback'); } - AutocompleteHelper::chooseValue($this->getSession(), $filterAutocomplete, $value); - } - - public function checkIfRuleConfigurationFormIsVisible(): bool - { - return $this->hasElement('count'); - } - - public function checkIfActionConfigurationFormIsVisible(): bool - { - return $this->hasElement('amount'); - } - - public function hasLabel(string $label, string $localeCode): bool - { - $this->getDocument()->find('css', 'div[data-locale="' . $localeCode . '"]')->click(); - - $labelElement = $this->getDocument()->find('css', sprintf('label:contains("%s")', $label)); - if (null === $labelElement) { - return false; - } - - return $labelElement->hasClass(sprintf('sylius-locale-%s', $localeCode)); + return $validationMessage->getText(); } protected function getDefinedElements(): array { - return [ - 'actions' => '#sylius_promotion_actions', + return array_merge(parent::getDefinedElements(), [ 'code' => '#sylius_promotion_code', - 'ends_at' => '#sylius_promotion_endsAt', - 'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min', - 'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max', - 'name' => '#sylius_promotion_name', + 'form' => '[data-live-name-value="sylius_admin:promotion:form"]', 'rules' => '#sylius_promotion_rules', - 'starts_at' => '#sylius_promotion_startsAt', - 'count' => '#sylius_promotion_rules_0_configuration_count', - 'amount' => '#sylius_promotion_actions_0_configuration_WEB-US_amount', - ]; + ]); } - private function getChannelConfigurationOfLastAction(string $channelCode): NodeElement + /** @throws ElementNotFoundException */ + private function getFieldElement(string $element): ?NodeElement { - $lastAction = $this->getLastCollectionItem('actions'); + $element = $this->getElement($element); + while (null !== $element && !$element->hasClass('field')) { + $element = $element->getParent(); + } - TabsHelper::switchTab($this->getSession(), $lastAction, $channelCode); - - return $lastAction - ->find('css', sprintf('[id^="sylius_promotion_actions_"][id$="_configuration_%s"]', $channelCode)) - ; - } - - private function getChannelConfigurationOfLastRule(string $channelCode): NodeElement - { - $lastRule = $this->getLastCollectionItem('rules'); - - TabsHelper::switchTab($this->getSession(), $lastRule, $channelCode); - - return $lastRule - ->find('css', sprintf('[id^="sylius_promotion_rules_"][id$="_configuration_%s"]', $channelCode)) - ; - } - - private function getLastCollectionItem(string $collection): NodeElement - { - $items = $this->getCollectionItems($collection); - - Assert::notEmpty($items); - - return end($items); - } - - /** - * @return NodeElement[] - */ - private function getCollectionItems(string $collection): array - { - $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]'); - - Assert::isArray($items); - - return $items; + return $element; } } diff --git a/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php index 30a0fb094a..c1102bfd66 100644 --- a/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Promotion/CreatePageInterface.php @@ -13,65 +13,13 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Promotion; -use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; interface CreatePageInterface extends BaseCreatePageInterface { public function specifyCode(string $code): void; - public function specifyLabel(string $label, string $localeCode): void; - public function nameIt(string $name): void; - public function addRule(?string $ruleName): void; - - public function selectRuleOption(string $option, string $value, bool $multiple = false): void; - - /** - * @param string|string[] $value - */ - public function selectAutocompleteRuleOption(string $option, array|string $value, bool $multiple = false): void; - - public function fillRuleOption(string $option, string $value): void; - - public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void; - - public function addAction(?string $actionName): void; - - public function selectActionOption(string $option, string $value, bool $multiple = false): void; - - public function fillActionOption(string $option, string $value): void; - - public function fillActionOptionForChannel(string $channelCode, string $option, string $value): void; - - public function fillUsageLimit(string $limit): void; - - public function makeExclusive(): void; - - public function makeNotAppliesToDiscountedItem(): void; - - public function checkCouponBased(): void; - - public function checkChannel(string $name): void; - - public function setStartsAt(\DateTimeInterface $dateTime): void; - - public function setEndsAt(\DateTimeInterface $dateTime): void; - - /** - * @throws ElementNotFoundException - */ - public function getValidationMessageForAction(): string; - - /** - * @param string|string[] $value - */ - public function selectAutoCompleteFilterOption(string $option, array|string $value, bool $multiple = false): void; - - public function checkIfRuleConfigurationFormIsVisible(): bool; - - public function checkIfActionConfigurationFormIsVisible(): bool; - - public function hasLabel(string $label, string $localeCode): bool; + public function getValidationMessage(string $element): string; } diff --git a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php index f9072e2889..ec46e6cf4e 100644 --- a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePage.php @@ -14,7 +14,6 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Promotion; use Behat\Mink\Element\NodeElement; -use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Behaviour\ChecksCodeImmutability; use Sylius\Behat\Behaviour\CountsChannelBasedErrors; use Sylius\Behat\Behaviour\NamesIt; @@ -26,16 +25,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface use CountsChannelBasedErrors; use NamesIt; - public function setPriority(?int $priority): void - { - $this->getDocument()->fillField('Priority', $priority); - } - - public function getPriority(): int - { - return (int) $this->getElement('priority')->getValue(); - } - public function checkChannelsState(string $channelName): bool { $field = $this->getDocument()->findField($channelName); @@ -43,42 +32,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return (bool) $field->getValue(); } - public function fillUsageLimit(string $limit): void - { - $this->getDocument()->fillField('Usage limit', $limit); - } - - public function makeExclusive(): void - { - $this->getDocument()->checkField('Exclusive'); - } - - public function checkCouponBased(): void - { - $this->getDocument()->checkField('Coupon based'); - } - - public function checkChannel(string $name): void - { - $this->getDocument()->checkField($name); - } - - public function setStartsAt(\DateTimeInterface $dateTime): void - { - $timestamp = $dateTime->getTimestamp(); - - $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp)); - $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp)); - } - - public function setEndsAt(\DateTimeInterface $dateTime): void - { - $timestamp = $dateTime->getTimestamp(); - - $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp)); - $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp)); - } - public function hasStartsAt(\DateTimeInterface $dateTime): bool { $timestamp = $dateTime->getTimestamp(); @@ -167,21 +120,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return $this->countChannelErrors($this->getElement('rules'), $channelCode); } - /** - * @throws ElementNotFoundException - */ - public function getValidationMessageForTranslation(string $element, string $localeCode): string - { - $foundElement = $this->getElement($element, ['%localeCode%' => $localeCode])->getParent(); - - $validationMessage = $foundElement->find('css', '.sylius-validation-error'); - if (null === $validationMessage) { - throw new ElementNotFoundException($this->getSession(), 'Validation message', 'css', '.sylius-validation-error'); - } - - return $validationMessage->getText(); - } - protected function getCodeElement(): NodeElement { return $this->getElement('code'); @@ -189,26 +127,25 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface protected function getDefinedElements(): array { - return [ + return array_merge(parent::getDefinedElements(), [ 'action_field' => '[id^="sylius_promotion_actions_"][id$="_configuration_%channelCode%_%field%"]', 'actions' => '#actions', 'applies_to_discounted' => '#sylius_promotion_appliesToDiscounted', 'code' => '#sylius_promotion_code', - 'coupon_based' => '#sylius_promotion_couponBased', 'ends_at' => '#sylius_promotion_endsAt', 'ends_at_date' => '#sylius_promotion_endsAt_date', 'ends_at_time' => '#sylius_promotion_endsAt_time', 'exclusive' => '#sylius_promotion_exclusive', - 'label' => '#sylius_promotion_translations_%localeCode%_label', + 'coupon_based' => '#sylius_promotion_couponBased', 'name' => '#sylius_promotion_name', 'order_percentage_action_field' => '[id^="sylius_promotion_actions_"][id$="_configuration_percentage"]', 'priority' => '#sylius_promotion_priority', 'rule_amount' => '[id^="sylius_promotion_rules_"][id$="_configuration_%channelCode%_amount"]', 'rules' => '#rules', + 'usage_limit' => '#sylius_promotion_usageLimit', 'starts_at' => '#sylius_promotion_startsAt', 'starts_at_date' => '#sylius_promotion_startsAt_date', 'starts_at_time' => '#sylius_promotion_startsAt_time', - 'usage_limit' => '#sylius_promotion_usageLimit', - ]; + ]); } } diff --git a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php index 3f3804b1ff..be0d90f967 100644 --- a/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Promotion/UpdatePageInterface.php @@ -13,33 +13,16 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\Promotion; -use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface; interface UpdatePageInterface extends BaseUpdatePageInterface { - public function setPriority(?int $priority): void; - - public function getPriority(): int; - public function nameIt(string $name): void; public function checkChannelsState(string $channelName): bool; public function isCodeDisabled(): bool; - public function fillUsageLimit(string $limit): void; - - public function makeExclusive(): void; - - public function checkCouponBased(): void; - - public function checkChannel(string $name): void; - - public function setStartsAt(\DateTimeInterface $dateTime): void; - - public function setEndsAt(\DateTimeInterface $dateTime): void; - public function hasStartsAt(\DateTimeInterface $dateTime): bool; public function hasEndsAt(\DateTimeInterface $dateTime): bool; @@ -65,9 +48,4 @@ interface UpdatePageInterface extends BaseUpdatePageInterface public function getActionValidationErrorsCount(string $channelCode): int; public function getRuleValidationErrorsCount(string $channelCode): int; - - /** - * @throws ElementNotFoundException - */ - public function getValidationMessageForTranslation(string $element, string $localeCode): string; } diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php index 946d71f8f7..b19b8e74a6 100644 --- a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePage.php @@ -13,179 +13,8 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ShippingMethod; -use Behat\Mink\Element\NodeElement; -use Behat\Mink\Exception\ElementNotFoundException; -use Sylius\Behat\Behaviour\SpecifiesItsField; use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage; -use Sylius\Behat\Service\DriverHelper; -use Sylius\Behat\Service\TabsHelper; -use Sylius\Component\Core\Formatter\StringInflector; -use Webmozart\Assert\Assert; class CreatePage extends BaseCreatePage implements CreatePageInterface { - use SpecifiesItsField; - - public function specifyPosition(?int $position): void - { - $this->getDocument()->fillField('Position', $position); - } - - public function nameIt(string $name, string $language): void - { - $this->getDocument()->fillField(sprintf('sylius_shipping_method_translations_%s_name', $language), $name); - } - - public function describeIt(string $description, string $languageCode): void - { - $this->getDocument()->fillField( - sprintf('sylius_shipping_method_translations_%s_description', $languageCode), - $description, - ); - } - - public function specifyAmountForChannel(string $channelCode, string $amount): void - { - TabsHelper::switchTab($this->getSession(), $this->getElement('calculator_configuration'), $channelCode); - - $this->getElement('amount', ['%channelCode%' => $channelCode])->setValue($amount); - } - - public function chooseZone(string $name): void - { - $this->getDocument()->selectFieldOption('Zone', $name); - } - - public function chooseCalculator(string $name): void - { - $this->getDocument()->selectFieldOption('Calculator', $name); - } - - public function checkChannel($channelName): void - { - if (DriverHelper::isJavascript($this->getDriver())) { - $this->getElement('channel', ['%channel%' => $channelName])->click(); - - return; - } - - $this->getDocument()->checkField($channelName); - } - - public function getValidationMessageForAmount(string $channelCode): string - { - $foundElement = $this->getFieldElement('amount', ['%channelCode%' => $channelCode]); - - return $this->getValidationMessageForElement($foundElement); - } - - public function getValidationMessageForRuleAmount(string $channelCode): string - { - $foundElement = $this->getChannelConfigurationOfLastRule($channelCode); - - return $this->getValidationMessageForElement($foundElement); - } - - public function addRule(string $ruleName): void - { - $count = count($this->getCollectionItems('rules')); - - $this->getDocument()->clickLink('Add rule'); - - $this->getDocument()->waitFor(5, fn () => $count + 1 === count($this->getCollectionItems('rules'))); - - $this->selectRuleOption('Type', $ruleName); - } - - public function selectRuleOption(string $option, string $value, bool $multiple = false): void - { - $this->getLastCollectionItem('rules')->find('named', ['select', $option])->selectOption($value, $multiple); - } - - public function fillRuleOption(string $option, string $value): void - { - $this->getLastCollectionItem('rules')->fillField($option, $value); - } - - public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void - { - $lastAction = $this->getChannelConfigurationOfLastRule($channelCode); - $lastAction->fillField($option, $value); - } - - protected function getDefinedElements(): array - { - return array_merge(parent::getDefinedElements(), [ - 'amount' => '#sylius_shipping_method_configuration_%channelCode%_amount', - 'channel' => '#sylius_shipping_method_channels .ui.checkbox:contains("%channel%")', - 'calculator' => '#sylius_shipping_method_calculator', - 'calculator_configuration' => '.ui.segment.configuration', - 'weight' => '[id*="sylius_shipping_method_rules_"][id*="_configuration_weight"]', - 'code' => '#sylius_shipping_method_code', - 'name' => '#sylius_shipping_method_translations_en_US_name', - 'zone' => '#sylius_shipping_method_zone', - 'rules' => '#sylius_shipping_method_rules', - ]); - } - - private function getValidationMessageForElement(NodeElement $element): string - { - if (null === $element) { - throw new ElementNotFoundException($this->getSession(), 'Field element'); - } - - $validationMessage = $element->find('css', '.sylius-validation-error'); - if (null === $validationMessage) { - throw new ElementNotFoundException( - $this->getSession(), - 'Validation message', - 'css', - '.sylius-validation-error', - ); - } - - return $validationMessage->getText(); - } - - /** - * @throws ElementNotFoundException - */ - private function getFieldElement(string $element, array $parameters = []): ?NodeElement - { - $element = $this->getElement(StringInflector::nameToCode($element), $parameters); - while (null !== $element && !$element->hasClass('field')) { - $element = $element->getParent(); - } - - return $element; - } - - private function getLastCollectionItem(string $collection): NodeElement - { - $items = $this->getCollectionItems($collection); - - Assert::notEmpty($items); - - return end($items); - } - - /** - * @return NodeElement[] - */ - private function getCollectionItems(string $collection): array - { - $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]'); - - Assert::isArray($items); - - return $items; - } - - private function getChannelConfigurationOfLastRule(string $channelCode): ?NodeElement - { - return $this - ->getLastCollectionItem('rules') - ->find('css', sprintf('[id^="sylius_shipping_method_rules_"][id$="_configuration_%s"]', $channelCode)) - ; - } } diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php index aee0845836..6655e45406 100644 --- a/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/CreatePageInterface.php @@ -13,38 +13,8 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ShippingMethod; -use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; interface CreatePageInterface extends BaseCreatePageInterface { - public function specifyCode(string $code): void; - - public function specifyPosition(?int $position): void; - - public function nameIt(string $name, string $language): void; - - public function describeIt(string $description, string $languageCode): void; - - public function specifyAmountForChannel(string $channelCode, string $amount): void; - - public function chooseZone(string $name): void; - - public function chooseCalculator(string $name): void; - - public function checkChannel(string $channelName): void; - - /** @throws ElementNotFoundException */ - public function getValidationMessageForAmount(string $channelCode): string; - - /** @throws ElementNotFoundException */ - public function getValidationMessageForRuleAmount(string $channelCode): string; - - public function addRule(string $ruleName): void; - - public function selectRuleOption(string $option, string $value, bool $multiple = false): void; - - public function fillRuleOption(string $option, string $value): void; - - public function fillRuleOptionForChannel(string $channelCode, string $option, string $value): void; } diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php index 193d85483d..9a2e91f199 100644 --- a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php +++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPage.php @@ -13,12 +13,19 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ShippingMethod; +use Behat\Mink\Element\NodeElement; use Sylius\Behat\Page\Admin\Crud\IndexPage as BaseIndexPage; +use Sylius\Component\Core\Model\ShippingMethodInterface; +use Sylius\Component\Resource\Model\ResourceInterface; class IndexPage extends BaseIndexPage implements IndexPageInterface { public function chooseArchival(string $isArchival): void { + if (!$this->areFiltersVisible()) { + $this->toggleFilters(); + } + $this->getElement('filter_archival')->selectOption($isArchival); } @@ -29,10 +36,52 @@ class IndexPage extends BaseIndexPage implements IndexPageInterface return null !== $archival; } + public function archiveShippingMethod(string $name): void + { + $actions = $this->getActionsForResource(['name' => $name]); + $actions->pressButton('archive'); + $this->getElement('confirm_action_button')->press(); + } + + public function deleteShippingMethod(string $name): void + { + $this->open(); + $this->deleteResourceOnPage(['name' => $name]); + $this->getElement('confirm_action_button')->press(); + } + + public function restoreShippingMethod(string $name): void + { + $actions = $this->getActionsForResource(['name' => $name]); + $actions->pressButton('Restore'); + $this->getElement('confirm_action_button')->press(); + } + + public function isShippingMethodDisabled(ShippingMethodInterface $shippingMethod): bool + { + $this->open(); + + return null !== $this->getRowFor($shippingMethod)->find('css', '[data-test-status-disabled]'); + } + + public function isShippingMethodEnabled(ShippingMethodInterface $shippingMethod): bool + { + $this->open(); + + return null !== $this->getRowFor($shippingMethod)->find('css', '[data-test-status-enabled]'); + } + + private function getRowFor(ResourceInterface $shippingMethod): NodeElement + { + return $this->getElement('row', ['%resourceId%' => $shippingMethod->getId()]); + } + protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ + 'confirm_action_button' => '[data-confirm-btn-true]', 'filter_archival' => '#criteria_archival', + 'row' => '[data-test-row][data-test-resource-id="%resourceId%"]', ]); } } diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php index b476112a23..3f9527a1be 100644 --- a/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php +++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/IndexPageInterface.php @@ -14,10 +14,21 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ShippingMethod; use Sylius\Behat\Page\Admin\Crud\IndexPageInterface as BaseIndexPageInterface; +use Sylius\Component\Core\Model\ShippingMethodInterface; interface IndexPageInterface extends BaseIndexPageInterface { public function chooseArchival(string $isArchival): void; public function isArchivalFilterEnabled(): bool; + + public function archiveShippingMethod(string $name): void; + + public function deleteShippingMethod(string $name): void; + + public function restoreShippingMethod(string $name): void; + + public function isShippingMethodEnabled(ShippingMethodInterface $shippingMethod): bool; + + public function isShippingMethodDisabled(ShippingMethodInterface $shippingMethod): bool; } diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php index 0e3b75f4b9..45a4022c4c 100644 --- a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePage.php @@ -13,65 +13,8 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ShippingMethod; -use Behat\Mink\Element\NodeElement; -use Sylius\Behat\Behaviour\ChecksCodeImmutability; -use Sylius\Behat\Behaviour\CountsChannelBasedErrors; -use Sylius\Behat\Behaviour\Toggles; use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage; class UpdatePage extends BaseUpdatePage implements UpdatePageInterface { - use ChecksCodeImmutability; - use CountsChannelBasedErrors; - use Toggles; - - public function isAvailableInChannel(string $channelName): bool - { - return $this->getElement('channel', ['%channel%' => $channelName])->hasAttribute('checked'); - } - - public function removeZone(): void - { - $this->getDocument()->selectFieldOption('Zone', 'Select'); - } - - public function removeShippingChargesAmount(string $channelCode): void - { - $this->getElement('amount', ['%channelCode%' => $channelCode])->setValue(''); - } - - public function getValidationMessageForAmount(string $channelCode): string - { - $foundElement = $this->getElement('amount', ['%channelCode%' => $channelCode]); - - return $foundElement->find('css', '.sylius-validation-error')->getText(); - } - - public function getShippingChargesValidationErrorsCount(string $channelCode): int - { - return $this->countChannelErrors($this->getElement('shipping_charges'), $channelCode); - } - - protected function getCodeElement(): NodeElement - { - return $this->getElement('code'); - } - - protected function getToggleableElement(): NodeElement - { - return $this->getElement('enabled'); - } - - protected function getDefinedElements(): array - { - return array_merge(parent::getDefinedElements(), [ - 'amount' => '#sylius_shipping_method_configuration_%channelCode%_amount', - 'channel' => '.checkbox:contains("%channel%") input', - 'code' => '#sylius_shipping_method_code', - 'enabled' => '#sylius_shipping_method_enabled', - 'name' => '#sylius_shipping_method_translations_en_US_name', - 'shipping_charges' => '.ui.segment.configuration', - 'zone' => '#sylius_shipping_method_zone', - ]); - } } diff --git a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php index b726c4115c..4638f88ab5 100644 --- a/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/ShippingMethod/UpdatePageInterface.php @@ -13,27 +13,8 @@ declare(strict_types=1); namespace Sylius\Behat\Page\Admin\ShippingMethod; -use Behat\Mink\Exception\ElementNotFoundException; use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface; interface UpdatePageInterface extends BaseUpdatePageInterface { - public function isCodeDisabled(): bool; - - public function isAvailableInChannel(string $channelName): bool; - - public function enable(): void; - - public function disable(): void; - - public function removeZone(): void; - - public function removeShippingChargesAmount(string $channelCode): void; - - /** - * @throws ElementNotFoundException - */ - public function getValidationMessageForAmount(string $channelCode): string; - - public function getShippingChargesValidationErrorsCount(string $channelCode): int; } diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php index 9b25c87011..d4b0dab873 100644 --- a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePage.php @@ -21,61 +21,15 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface { use NamesIt; use SpecifiesItsField; - - public function chooseZone(string $name): void - { - $this->getDocument()->selectFieldOption('Zone', $name); - } - - public function chooseCategory(string $name): void - { - $this->getDocument()->selectFieldOption('Category', $name); - } - - public function chooseCalculator(string $name): void - { - $this->getDocument()->selectFieldOption('Calculator', $name); - } - - public function specifyAmount(string $amount): void - { - $this->getDocument()->fillField('Amount', $amount); - } - - public function specifyStartDate(\DateTimeInterface $startDate): void - { - $timestamp = $startDate->getTimestamp(); - - $this->getElement('start_date')->setValue(date('Y-m-d', $timestamp)); - $this->getElement('start_date_time')->setValue(date('H:i', $timestamp)); - } - - public function specifyEndDate(\DateTimeInterface $endDate): void - { - $timestamp = $endDate->getTimestamp(); - - $this->getElement('end_date')->setValue(date('Y-m-d', $timestamp)); - $this->getElement('end_date_time')->setValue(date('H:i', $timestamp)); - } + use FormAwareTrait; public function chooseIncludedInPrice(): void { - $this->getDocument()->find('css', 'label[for=sylius_tax_rate_includedInPrice]')->click(); + $this->getElement('field_included_in_price')->check(); } protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'amount' => '#sylius_tax_rate_amount', - 'calculator' => '#sylius_tax_rate_calculator', - 'category' => '#sylius_tax_rate_category', - 'code' => '#sylius_tax_rate_code', - 'end_date' => '#sylius_tax_rate_endDate_date', - 'end_date_time' => '#sylius_tax_rate_endDate_time', - 'name' => '#sylius_tax_rate_name', - 'start_date' => '#sylius_tax_rate_startDate_date', - 'start_date_time' => '#sylius_tax_rate_startDate_time', - 'zone' => '#sylius_tax_rate_zone', - ]); + return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements()); } } diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php index 324e3d6f2c..e9374a988a 100644 --- a/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/TaxRate/CreatePageInterface.php @@ -15,23 +15,9 @@ namespace Sylius\Behat\Page\Admin\TaxRate; use Sylius\Behat\Page\Admin\Crud\CreatePageInterface as BaseCreatePageInterface; -interface CreatePageInterface extends BaseCreatePageInterface +interface CreatePageInterface extends BaseCreatePageInterface, FormAwareInterface { public function specifyCode(string $code): void; - public function nameIt(string $name): void; - - public function specifyAmount(string $amount): void; - - public function specifyStartDate(\DateTimeInterface $startDate): void; - - public function specifyEndDate(\DateTimeInterface $endDate): void; - - public function chooseZone(string $name): void; - - public function chooseCategory(string $name): void; - - public function chooseCalculator(string $name): void; - public function chooseIncludedInPrice(): void; } diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/FormAwareInterface.php b/src/Sylius/Behat/Page/Admin/TaxRate/FormAwareInterface.php new file mode 100644 index 0000000000..67d2ad696f --- /dev/null +++ b/src/Sylius/Behat/Page/Admin/TaxRate/FormAwareInterface.php @@ -0,0 +1,31 @@ +getElement('field_zone')->selectOption($name); + } + + public function chooseCategory(string $name): void + { + $this->getElement('field_category')->selectOption($name); + } + + public function chooseCalculator(string $name): void + { + $this->getElement('field_calculator')->selectOption($name); + } + + public function specifyAmount(string $amount): void + { + $this->getElement('field_amount')->setValue($amount); + } + + public function specifyStartDate(\DateTimeInterface $startDate): void + { + $timestamp = $startDate->getTimestamp(); + + $this->getElement('field_start_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('field_start_date_time')->setValue(date('H:i', $timestamp)); + } + + public function specifyEndDate(\DateTimeInterface $endDate): void + { + $timestamp = $endDate->getTimestamp(); + + $this->getElement('field_end_date')->setValue(date('Y-m-d', $timestamp)); + $this->getElement('field_end_date_time')->setValue(date('H:i', $timestamp)); + } + + /** @return array */ + protected function getDefinedFormElements(): array + { + return [ + 'field_amount' => '#sylius_tax_rate_amount', + 'field_calculator' => '#sylius_tax_rate_calculator', + 'field_category' => '#sylius_tax_rate_category', + 'field_code' => '#sylius_tax_rate_code', + 'field_end_date' => '#sylius_tax_rate_endDate_date', + 'field_end_date_time' => '#sylius_tax_rate_endDate_time', + 'field_included_in_price' => '#sylius_tax_rate_includedInPrice', + 'field_name' => '#sylius_tax_rate_name', + 'field_start_date' => '#sylius_tax_rate_startDate_date', + 'field_start_date_time' => '#sylius_tax_rate_startDate_time', + 'field_zone' => '#sylius_tax_rate_zone', + ]; + } +} diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php index dbe3860bb6..24a8a08315 100644 --- a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePage.php @@ -19,33 +19,26 @@ use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage; class UpdatePage extends BaseUpdatePage implements UpdatePageInterface { + use FormAwareTrait; use ChecksCodeImmutability; public function removeZone(): void { - $this->getDocument()->selectFieldOption('Zone', 'Select'); + $this->getElement('field_zone')->setValue(''); } public function isIncludedInPrice(): bool { - return (bool) $this->getElement('included_in_price')->getValue(); + return $this->getElement('field_included_in_price')->isChecked(); } protected function getCodeElement(): NodeElement { - return $this->getElement('code'); + return $this->getElement('field_code'); } protected function getDefinedElements(): array { - return array_merge(parent::getDefinedElements(), [ - 'amount' => '#sylius_tax_rate_amount', - 'calculator' => '#sylius_tax_rate_calculator', - 'category' => '#sylius_tax_rate_category', - 'code' => '#sylius_tax_rate_code', - 'name' => '#sylius_tax_rate_name', - 'zone' => '#sylius_tax_rate_zone', - 'included_in_price' => '#sylius_tax_rate_includedInPrice', - ]); + return array_merge(parent::getDefinedElements(), $this->getDefinedFormElements()); } } diff --git a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php index d08c49b492..b8fd6c860f 100644 --- a/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/TaxRate/UpdatePageInterface.php @@ -15,9 +15,11 @@ namespace Sylius\Behat\Page\Admin\TaxRate; use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface as BaseUpdatePageInterface; -interface UpdatePageInterface extends BaseUpdatePageInterface +interface UpdatePageInterface extends BaseUpdatePageInterface, FormAwareInterface { public function isCodeDisabled(): bool; + public function isIncludedInPrice(): bool; + public function removeZone(): void; } diff --git a/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php b/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php index 4027cbaf2f..1448fea15f 100644 --- a/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php +++ b/src/Sylius/Behat/Page/Admin/Taxon/CreatePage.php @@ -73,35 +73,6 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface return 0 !== $this->countTaxonsByName($name); } - public function nameIt(string $name, string $languageCode): void - { - $this->activateLanguageTab($languageCode); - $this->getElement('name', ['%language%' => $languageCode])->setValue($name); - - if (DriverHelper::isJavascript($this->getDriver())) { - SlugGenerationHelper::waitForSlugGeneration( - $this->getSession(), - $this->getElement('slug', ['%language%' => $languageCode]), - ); - } - } - - public function specifySlug(string $slug, string $languageCode): void - { - $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_slug', $languageCode), $slug); - } - - public function attachImage(string $path, ?string $type = null): void - { - $filesPath = $this->getParameter('files_path'); - - $this->getDocument()->find('css', '[data-form-collection="add"]')->click(); - - $imageForm = $this->getLastImageElement(); - $imageForm->fillField('Type', $type); - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - public function getLeaves(?TaxonInterface $parentTaxon = null): array { return $this->getDocument()->findAll('css', '.sylius-tree__item'); @@ -166,7 +137,6 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface 'code' => '#sylius_taxon_code', 'confirmation_button' => '#confirmation-button', 'description' => '#sylius_taxon_translations_en_US_description', - 'images' => '#sylius_taxon_images', 'language_tab' => '[data-locale="%locale%"] .title', 'name' => '#sylius_taxon_translations_%language%_name', 'slug' => '#sylius_taxon_translations_%language%_slug', @@ -174,14 +144,4 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface 'tree_item' => '.sylius-tree__item a:contains("%taxon%")', ]); } - - private function getLastImageElement(): NodeElement - { - $images = $this->getElement('images'); - $items = $images->findAll('css', 'div[data-form-collection="item"]'); - - Assert::notEmpty($items); - - return end($items); - } } diff --git a/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php index 25d5667ed1..b0ebdb429e 100644 --- a/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Taxon/CreatePageInterface.php @@ -30,14 +30,8 @@ interface CreatePageInterface extends BaseCreatePageInterface public function hasTaxonWithName(string $name): bool; - public function nameIt(string $name, string $languageCode): void; - public function specifyCode(string $code): void; - public function specifySlug(string $slug, string $languageCode): void; - - public function attachImage(string $path, ?string $type = null): void; - /** * @return NodeElement[] * diff --git a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php index 0a5a21cac2..ef9de2cd40 100644 --- a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php +++ b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePage.php @@ -41,54 +41,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_description', $languageCode), $description); } - public function nameIt(string $name, string $languageCode): void - { - $this->activateLanguageTab($languageCode); - $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_name', $languageCode), $name); - - if (DriverHelper::isJavascript($this->getDriver())) { - SlugGenerationHelper::waitForSlugGeneration( - $this->getSession(), - $this->getElement('slug', ['%language%' => $languageCode]), - ); - } - } - - public function specifySlug(string $slug, string $languageCode): void - { - $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_slug', $languageCode), $slug); - } - - public function attachImage(string $path, ?string $type = null): void - { - $filesPath = $this->getParameter('files_path'); - - $this->getDocument()->find('css', '[data-form-collection="add"]')->click(); - - $imageForm = $this->getLastImageElement(); - if (null !== $type) { - $imageForm->fillField('Type', $type); - } - - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function isImageWithTypeDisplayed(string $type): bool - { - $imageElement = $this->getImageElementByType($type); - - $imageUrl = $imageElement ? $imageElement->find('css', 'img')->getAttribute('src') : $this->provideImageUrlForType($type); - if (null === $imageElement && null === $imageUrl) { - return false; - } - - $this->getDriver()->visit($imageUrl); - $statusCode = $this->getDriver()->getStatusCode(); - $this->getDriver()->back(); - - return in_array($statusCode, [200, 304], true); - } - public function isSlugReadonly(string $languageCode = 'en_US'): bool { return SlugGenerationHelper::isSlugReadonly( @@ -97,33 +49,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface ); } - public function removeImageWithType(string $type): void - { - $imageElement = $this->getImageElementByType($type); - $imageSourceElement = $imageElement->find('css', 'img'); - if (null !== $imageSourceElement) { - $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src')); - } - - $imageElement->clickLink('Delete'); - } - - public function removeFirstImage(): void - { - $imageElement = $this->getFirstImageElement(); - $imageTypeElement = $imageElement->find('css', 'input[type=text]'); - $imageSourceElement = $imageElement->find('css', 'img'); - - if (null !== $imageTypeElement && null !== $imageSourceElement) { - $this->saveImageUrlForType( - $imageTypeElement->getValue(), - $imageSourceElement->getAttribute('src'), - ); - } - - $imageElement->clickLink('Delete'); - } - public function enableSlugModification(string $languageCode = 'en_US'): void { SlugGenerationHelper::enableSlugModification( @@ -132,29 +57,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface ); } - public function countImages(): int - { - $imageElements = $this->getImageElements(); - - return count($imageElements); - } - - public function changeImageWithType(string $type, string $path): void - { - $filesPath = $this->getParameter('files_path'); - - $imageForm = $this->getImageElementByType($type); - $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path); - } - - public function modifyFirstImageType(string $type): void - { - $firstImage = $this->getFirstImageElement(); - - $typeField = $firstImage->findField('Type'); - $typeField->setValue($type); - } - public function getParent(): string { return $this->getElement('parent')->getValue(); @@ -238,7 +140,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface 'code' => '#sylius_taxon_code', 'description' => '#sylius_taxon_translations_en_US_description', 'enabled' => '#sylius_taxon_enabled', - 'images' => '#sylius_taxon_images', 'language_tab' => '[data-locale="%locale%"] .title', 'name' => '#sylius_taxon_translations_en_US_name', 'parent' => '#sylius_taxon_parent', @@ -256,15 +157,6 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return end($imageElements); } - private function getFirstImageElement(): NodeElement - { - $imageElements = $this->getImageElements(); - - Assert::notEmpty($imageElements); - - return reset($imageElements); - } - /** * @return NodeElement[] */ @@ -274,30 +166,4 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface return $images->findAll('css', 'div[data-form-collection="item"]'); } - - private function getImageElementByType(string $type): ?NodeElement - { - $images = $this->getElement('images'); - $typeInput = $images->find('css', 'input[value="' . $type . '"]'); - - if (null === $typeInput) { - return null; - } - - return $typeInput->getParent()->getParent()->getParent(); - } - - private function provideImageUrlForType(string $type): ?string - { - return $this->imageUrls[$type] ?? null; - } - - private function saveImageUrlForType(string $type, string $imageUrl): void - { - if (str_contains($imageUrl, 'data:image/jpeg')) { - return; - } - - $this->imageUrls[$type] = $imageUrl; - } } diff --git a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php index 9740f748a9..bb65f67be9 100644 --- a/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php +++ b/src/Sylius/Behat/Page/Admin/Taxon/UpdatePageInterface.php @@ -25,28 +25,10 @@ interface UpdatePageInterface extends BaseUpdatePageInterface public function isCodeDisabled(): bool; - public function nameIt(string $name, string $languageCode): void; - - public function specifySlug(string $slug, string $languageCode): void; - - public function attachImage(string $path, ?string $type = null): void; - - public function isImageWithTypeDisplayed(string $type): bool; - public function isSlugReadonly(string $languageCode = 'en_US'): bool; - public function removeImageWithType(string $type): void; - - public function removeFirstImage(): void; - public function enableSlugModification(string $languageCode = 'en_US'): void; - public function countImages(): int; - - public function changeImageWithType(string $type, string $path): void; - - public function modifyFirstImageType(string $type): void; - public function getParent(): string; public function getSlug(string $languageCode = 'en_US'): string; diff --git a/src/Sylius/Behat/Page/Admin/Zone/CreatePage.php b/src/Sylius/Behat/Page/Admin/Zone/CreatePage.php deleted file mode 100644 index ba46579d45..0000000000 --- a/src/Sylius/Behat/Page/Admin/Zone/CreatePage.php +++ /dev/null @@ -1,80 +0,0 @@ -getDocument()->clickLink('Add member'); - } - - public function checkValidationMessageForMembers(string $message): bool - { - $membersValidationElement = $this->getElement('ui_segment')->find('css', '.sylius-validation-error'); - if (null === $membersValidationElement) { - throw new ElementNotFoundException($this->getDriver(), 'members validation box', 'css', '.sylius-validation-error'); - } - - return $membersValidationElement->getText() === $message; - } - - public function chooseMember(string $name): void - { - $selectItems = $this->getDocument()->waitFor(2, fn () => $this->getDocument()->findAll('css', 'div[data-form-type="collection"] select')); - $lastSelectItem = end($selectItems); - - if (false === $lastSelectItem) { - throw new ElementNotFoundException($this->getSession(), 'select', 'css', 'div[data-form-type="collection"] select'); - } - - $lastSelectItem->selectOption($name); - } - - public function selectScope(string $scope): void - { - $this->getDocument()->selectFieldOption('Scope', $scope); - } - - public function hasType(string $type): bool - { - $typeField = $this->getElement('type'); - $selectedOption = $typeField->find('css', 'option[selected]'); - - return lcfirst($selectedOption->getText()) === $type; - } - - public function isTypeFieldDisabled(): bool - { - return $this->getElement('type')->hasAttribute('disabled'); - } - - protected function getDefinedElements(): array - { - return array_merge(parent::getDefinedElements(), [ - 'code' => '#sylius_zone_code', - 'name' => '#sylius_zone_name', - 'type' => '#sylius_zone_type', - 'ui_segment' => '.ui.segment', - ]); - } -} diff --git a/src/Sylius/Behat/Page/Admin/Zone/CreatePageInterface.php b/src/Sylius/Behat/Page/Admin/Zone/CreatePageInterface.php deleted file mode 100644 index ba270d76e2..0000000000 --- a/src/Sylius/Behat/Page/Admin/Zone/CreatePageInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -getSelectedZoneMembers(); - - return count($selectedZoneMembers); - } - - public function getScope(): string - { - return $this->getElement('scope')->getValue(); - } - - public function hasMember(ZoneMemberInterface $zoneMember): bool - { - $selectedZoneMembers = $this->getSelectedZoneMembers(); - - foreach ($selectedZoneMembers as $selectedZoneMember) { - if ($selectedZoneMember->getValue() === $zoneMember->getCode()) { - return true; - } - } - - return false; - } - - public function removeMember(ZoneMemberInterface $zoneMember): void - { - $zoneMembers = $this->getElement('zone_members'); - $items = $zoneMembers->findAll('css', 'div[data-form-collection="item"]'); - - /** @var NodeElement $item */ - foreach ($items as $item) { - $selectedItem = $item->find('css', 'option[selected="selected"]'); - - if (null === $selectedItem) { - throw new ElementNotFoundException($this->getDriver(), 'selected option', 'css', 'option[selected="selected"]'); - } - - if ($selectedItem->getValue() === $zoneMember->getCode()) { - $this->getDeleteButtonForCollectionItem($item)->click(); - - break; - } - } - } - - /** - * @throws ElementNotFoundException - */ - protected function getCodeElement(): NodeElement - { - return $this->getElement('code'); - } - - protected function getDefinedElements(): array - { - return array_merge(parent::getDefinedElements(), [ - 'code' => '#sylius_zone_code', - 'member' => '.one.field', - 'name' => '#sylius_zone_name', - 'scope' => '#sylius_zone_scope', - 'type' => '#sylius_zone_type', - 'zone_members' => '#sylius_zone_members', - ]); - } - - /** - * @throws ElementNotFoundException - */ - private function getDeleteButtonForCollectionItem(NodeElement $item): NodeElement - { - $deleteButton = $item->find('css', 'a[data-form-collection="delete"]'); - if (null === $deleteButton) { - throw new ElementNotFoundException($this->getDriver(), 'link', 'css', 'a[data-form-collection="delete"]'); - } - - return $deleteButton; - } - - /** - * @return NodeElement[] - * - * @throws ElementNotFoundException - */ - private function getSelectedZoneMembers(): array - { - $zoneMembers = $this->getElement('zone_members'); - - return $zoneMembers->findAll('css', 'option[selected="selected"]'); - } -} diff --git a/src/Sylius/Behat/Page/Admin/Zone/UpdatePageInterface.php b/src/Sylius/Behat/Page/Admin/Zone/UpdatePageInterface.php deleted file mode 100644 index bcc006d9a4..0000000000 --- a/src/Sylius/Behat/Page/Admin/Zone/UpdatePageInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - %kernel.project_dir%/var/date.txt + [data-test-sylius-flash-message] + .sylius-flash-message + + alert-danger + alert-info + alert-success + + + negative + info + positive + @@ -86,12 +98,24 @@ - + + %sylius.behat.notification_accessor.admin.locator% - - + + + %sylius.behat.notification_accessor.shop.locator% + + + + + %sylius.behat.notification_checker.admin.class_map% + + + + + %sylius.behat.notification_checker.shop.class_map% @@ -101,6 +125,8 @@ + + 1000000 7 diff --git a/src/Sylius/Behat/Resources/config/services/contexts/ui.xml b/src/Sylius/Behat/Resources/config/services/contexts/ui.xml index 135272efe4..f5405cc693 100644 --- a/src/Sylius/Behat/Resources/config/services/contexts/ui.xml +++ b/src/Sylius/Behat/Resources/config/services/contexts/ui.xml @@ -35,7 +35,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -82,7 +82,7 @@ - + @@ -120,7 +120,7 @@ - + @@ -129,22 +129,25 @@ - - + + + + + - + - + @@ -153,7 +156,6 @@ - Offline Paypal Express Checkout @@ -189,7 +191,7 @@ - + @@ -199,7 +201,8 @@ - + + @@ -219,7 +222,7 @@ - + @@ -233,7 +236,7 @@ - + @@ -252,7 +255,7 @@ - + @@ -262,15 +265,15 @@ - + - - + + @@ -295,8 +298,10 @@ + + - + @@ -310,16 +315,15 @@ - + - - + + - - + @@ -327,25 +331,26 @@ + - + - + - + @@ -410,7 +415,7 @@ - + @@ -459,7 +464,7 @@ - + @@ -470,7 +475,7 @@ - + @@ -486,14 +491,14 @@ - + - + @@ -518,7 +523,7 @@ - + @@ -542,7 +547,7 @@ - + @@ -556,7 +561,7 @@ - + diff --git a/src/Sylius/Behat/Resources/config/services/elements/admin.xml b/src/Sylius/Behat/Resources/config/services/elements/admin.xml index 839891a9a6..918274b37d 100644 --- a/src/Sylius/Behat/Resources/config/services/elements/admin.xml +++ b/src/Sylius/Behat/Resources/config/services/elements/admin.xml @@ -16,20 +16,32 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" > + + + + - + + + + + + parent="sylius.behat.element.admin.crud.form" + > + + + + + + + + + + + + diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml index 222aca9d32..a1e1efe886 100644 --- a/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml +++ b/src/Sylius/Behat/Resources/config/services/pages/admin/channel.xml @@ -23,12 +23,14 @@ sylius_admin_channel_create + sylius_admin_channel_index sylius_admin_channel_update + diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml index 92948a9daa..58c5a51ef3 100644 --- a/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml +++ b/src/Sylius/Behat/Resources/config/services/pages/admin/customer.xml @@ -28,6 +28,7 @@ sylius_admin_customer_index + sylius_admin_customer_order_index diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml index f84437d4d4..6c3507a3d9 100644 --- a/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml +++ b/src/Sylius/Behat/Resources/config/services/pages/admin/order.xml @@ -27,7 +27,6 @@ - sylius_admin_order_update diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml index 74c8cfd354..a638ed1ff5 100644 --- a/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml +++ b/src/Sylius/Behat/Resources/config/services/pages/admin/product.xml @@ -27,9 +27,11 @@ sylius_admin_product_create + sylius_admin_product_create + sylius_admin_product_index @@ -40,9 +42,11 @@ sylius_admin_product_update + sylius_admin_product_update + diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml index 7aae42736e..cf8c1a23ed 100644 --- a/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml +++ b/src/Sylius/Behat/Resources/config/services/pages/admin/product_association_type.xml @@ -13,9 +13,9 @@ - Sylius\Behat\Page\Admin\ProductAssociationType\CreatePage + %sylius.behat.page.admin.crud.create.class% Sylius\Behat\Page\Admin\ProductAssociationType\IndexPage - Sylius\Behat\Page\Admin\ProductAssociationType\UpdatePage + %sylius.behat.page.admin.crud.update.class% diff --git a/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml b/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml index 2319e8aafd..8eac969c03 100644 --- a/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml +++ b/src/Sylius/Behat/Resources/config/services/pages/admin/zone.xml @@ -13,9 +13,9 @@ - Sylius\Behat\Page\Admin\Zone\CreatePage + %sylius.behat.page.admin.crud.create.class% %sylius.behat.page.admin.crud.index.class% - Sylius\Behat\Page\Admin\Zone\UpdatePage + %sylius.behat.page.admin.crud.update.class% diff --git a/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml b/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml index cd5d323ab3..8cdfaa3fb3 100644 --- a/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml +++ b/src/Sylius/Behat/Resources/config/suites/ui/inventory/displaying_inventory_on_edit_product_page.yml @@ -3,7 +3,7 @@ default: suites: - ui_managing_inventory: + ui_inventory_on_product_page: contexts: - sylius.behat.context.hook.doctrine_orm - sylius.behat.context.hook.session diff --git a/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml b/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml index 6541042c0f..55313fef7e 100644 --- a/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml +++ b/src/Sylius/Behat/Resources/config/suites/ui/order/modifying_placed_order_address.yaml @@ -35,6 +35,7 @@ default: - sylius.behat.context.transform.order - sylius.behat.context.transform.payment - sylius.behat.context.transform.product + - sylius.behat.context.transform.province - sylius.behat.context.transform.shipping_method - sylius.behat.context.transform.tax_category - sylius.behat.context.transform.tax_rate diff --git a/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml b/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml index 21f3ebd5ec..28068928d3 100644 --- a/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml +++ b/src/Sylius/Behat/Resources/config/suites/ui/order/order_history.yml @@ -25,10 +25,10 @@ default: - sylius.behat.context.transform.product - sylius.behat.context.transform.shipping_method - sylius.behat.context.transform.zone - - sylius.behat.context.transform.shared_storage - sylius.behat.context.ui.admin.managing_orders + - sylius.behat.context.ui.admin.order_history filters: tags: "@order_history&&@ui" diff --git a/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml b/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml index 8bec36025b..8a91b83d12 100644 --- a/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml +++ b/src/Sylius/Behat/Resources/config/suites/ui/shipping/managing_shipping_methods.yml @@ -18,6 +18,7 @@ default: - sylius.behat.context.transform.product - sylius.behat.context.transform.shared_storage - sylius.behat.context.transform.shipping_method + - sylius.behat.context.transform.zone - sylius.behat.context.setup.channel - sylius.behat.context.setup.currency diff --git a/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml b/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml index 7494a1b012..76e9655706 100644 --- a/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml +++ b/src/Sylius/Behat/Resources/config/suites/ui/user/managing_customers.yml @@ -10,6 +10,7 @@ default: - sylius.behat.context.hook.session - sylius.behat.context.transform.address + - sylius.behat.context.transform.channel - sylius.behat.context.transform.customer - sylius.behat.context.transform.customer_group - sylius.behat.context.transform.payment diff --git a/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php b/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php index 6cfe928930..88baa54f47 100644 --- a/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php +++ b/src/Sylius/Behat/Service/Accessor/NotificationAccessor.php @@ -16,18 +16,20 @@ namespace Sylius\Behat\Service\Accessor; use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Session; -final class NotificationAccessor implements NotificationAccessorInterface +final readonly class NotificationAccessor implements NotificationAccessorInterface { - public function __construct(private Session $session) - { + public function __construct( + private Session $session, + private string $locator, + ) { } public function getMessageElements(): array { - $messageElements = $this->session->getPage()->findAll('css', '.sylius-flash-message'); + $messageElements = $this->session->getPage()->findAll('css', $this->locator); if (empty($messageElements)) { - throw new ElementNotFoundException($this->session->getDriver(), 'message element', 'css', '.sylius-flash-message'); + throw new ElementNotFoundException($this->session->getDriver(), 'message element', 'css', $this->locator); } return $messageElements; diff --git a/src/Sylius/Behat/Service/Helper/AutocompleteHelper.php b/src/Sylius/Behat/Service/Helper/AutocompleteHelper.php new file mode 100644 index 0000000000..60cddbaa03 --- /dev/null +++ b/src/Sylius/Behat/Service/Helper/AutocompleteHelper.php @@ -0,0 +1,149 @@ +normalizeSelector($selector); + $result = $driver->evaluateScript(<< - -
-
- {% block sidebar %} - {% endblock %} -
- -
-
-
- -
-
- -
- -
- {% block flash_messages %} - {% include '@SyliusUi/_flashes.html.twig' %} - {% endblock %} - - {% block pre_content %} - {% endblock %} - - {% block content %} - {% endblock %} - - {% block post_content %} - {% endblock %} -
- - -
- - - - - {% include '@SyliusUi/Modal/_confirmation.html.twig' %} - - {% block javascripts %} - {% endblock %} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Locale/Grid/Field/name.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Locale/Grid/Field/name.html.twig deleted file mode 100644 index 74c5cb194d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Locale/Grid/Field/name.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import "@SyliusUi/Macro/flags.html.twig" as flags %} - -{{ flags.fromLocaleCode(data.code) }} {{ data.code }} {{ data.name }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Locale/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Locale/_form.html.twig deleted file mode 100644 index 79cfdf7bcf..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Locale/_form.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{{ form_errors(form) }} -
- {{ form_row(form.code) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Macro/breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Macro/breadcrumb.html.twig deleted file mode 100644 index a4bf8e8515..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Macro/breadcrumb.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% macro crumble(crumbs = {}) %} - {% import '@SyliusUi/Macro/breadcrumb.html.twig' as _breadcrumb %} - - {{ _breadcrumb.crumble(crumbs, path('sylius_admin_dashboard'), 'sylius.ui.administration'|trans) }} -{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Macro/translationForm.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Macro/translationForm.html.twig deleted file mode 100644 index e3698aed06..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Macro/translationForm.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{% macro translationForm(translations) %} - {% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -
- {% for locale, translationForm in translations %} -
-
- - {{ flags.fromLocaleCode(locale) }} {{ locale|sylius_locale_name }} -
-
- {% for field in translationForm %} - {{ form_row(field) }} - {% endfor %} -
-
- {% endfor %} -
-{% endmacro %} - -{% macro translationFormWithSlug(translations, slugFieldTemplate, resource) %} - {% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -
- {% for locale, translationForm in translations %} -
-
- - {{ flags.fromLocaleCode(locale) }} {{ locale|sylius_locale_name }} -
-
- {% for field in translationForm %} - {% if field.vars.name != 'slug' %} - {{ form_row(field) }} - {% else %} - {% include slugFieldTemplate with { 'slugField': translationForm.slug, 'resource': resource } %} - {% endif %} - {% endfor %} -
-
- {% endfor %} -
-{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/channel.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/channel.html.twig deleted file mode 100644 index 7341ba10bc..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/channel.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusAdmin/Common/_channel.html.twig' with {'channel': data} %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/number.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/number.html.twig deleted file mode 100644 index 2b25fa6b8a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/number.html.twig +++ /dev/null @@ -1 +0,0 @@ -#{{ data.number }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/total.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/total.html.twig deleted file mode 100644 index 13020f5f27..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/total.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -{{ money.format(data.total, data.currencyCode) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_actions.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_actions.html.twig deleted file mode 100644 index 0b21b92b94..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_actions.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ 'sylius.ui.return'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_address.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_address.html.twig deleted file mode 100644 index 7695098a90..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_address.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-

- {{ ('sylius.ui.'~type~'_address')|trans }} -

-
- {{ render(url('sylius_admin_partial_address_log_entry_index', {'id': address.id})) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_addresses.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_addresses.html.twig deleted file mode 100644 index f19ae63164..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_addresses.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -
-
-
- {% include '@SyliusAdmin/Order/History/_address.html.twig' with {'type': 'shipping', address: order.shippingAddress} %} -
-
- {% include '@SyliusAdmin/Order/History/_address.html.twig' with {'type': 'billing', address: order.billingAddress} %} -
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_breadcrumb.html.twig deleted file mode 100644 index 9b6a439d92..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_breadcrumb.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.orders'|trans, url: path('sylius_admin_order_index') }, - { label: '#'~order.number, url: path('sylius_admin_order_show', {'id': order.id}) }, - { label: 'sylius.ui.history'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_content.html.twig deleted file mode 100644 index 608083657d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_content.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -
-
- {% include '@SyliusAdmin/Order/History/_addresses.html.twig' %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_header.html.twig deleted file mode 100644 index 2f84e2cd14..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_header.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusAdmin/Order/Show/_header.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_headerWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_headerWidget.html.twig deleted file mode 100644 index 3f3c943f78..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/History/_headerWidget.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-
- {% include '@SyliusAdmin/Order/History/_header.html.twig' %} -
-
- {% include '@SyliusAdmin/Order/History/_actions.html.twig' %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/authorized.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/authorized.html.twig deleted file mode 100644 index 179354854b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/authorized.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/awaiting_payment.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/awaiting_payment.html.twig deleted file mode 100644 index ecfe4d8564..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/awaiting_payment.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/cancelled.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/cancelled.html.twig deleted file mode 100644 index a3d3dab88f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/cancelled.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/paid.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/paid.html.twig deleted file mode 100644 index 61e3eb92c1..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/paid.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_authorized.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_authorized.html.twig deleted file mode 100644 index 179354854b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_authorized.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_paid.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_paid.html.twig deleted file mode 100644 index 3a2dce9255..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_paid.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_refunded.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_refunded.html.twig deleted file mode 100644 index 74a81f519b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/partially_refunded.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/refunded.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/refunded.html.twig deleted file mode 100644 index b726dd176e..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/PaymentState/refunded.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/cancelled.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/cancelled.html.twig deleted file mode 100644 index a3d3dab88f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/cancelled.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/partially_shipped.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/partially_shipped.html.twig deleted file mode 100644 index 3a2dce9255..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/partially_shipped.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/ready.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/ready.html.twig deleted file mode 100644 index c354ff98ee..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/ready.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/shipped.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/shipped.html.twig deleted file mode 100644 index 7cce852a33..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/ShippingState/shipped.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/cancelled.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/cancelled.html.twig deleted file mode 100644 index 9062a2782d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/cancelled.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/fulfilled.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/fulfilled.html.twig deleted file mode 100644 index 895532a778..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/fulfilled.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/new.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/new.html.twig deleted file mode 100644 index 2539898983..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Label/State/new.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_completeTransition.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_completeTransition.html.twig deleted file mode 100644 index 002ba9306b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_completeTransition.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if sylius_sm_can(payment, 'sylius_payment', 'complete') %} -
-
- - - -
-
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_content.html.twig deleted file mode 100644 index 3b9a1a73a9..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_content.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -
-
- {{ payment.method }} -
-
- {{ money.format(payment.amount, payment.order.currencyCode) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_header.html.twig deleted file mode 100644 index b89c5a3104..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_header.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -
- {% include '@SyliusAdmin/Common/Label/paymentState.html.twig' with {'data': payment.state} %} -
- diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_refundTransition.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_refundTransition.html.twig deleted file mode 100644 index 238f10b12f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Payment/_refundTransition.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if sylius_sm_can(payment, 'sylius_payment', 'refund') %} -
-
- - - -
-
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_content.html.twig deleted file mode 100644 index f170a2f0b0..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_content.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -
-
- {{ shipment.method }} -
-
- {{ shipment.method.zone }} -
- {% if shipment.shippedAt is not empty %} - {{ 'sylius.ui.shipped_at'|trans }}: {{ shipment.shippedAt|date('d-m-Y H:i:s') }} - {% endif %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_header.html.twig deleted file mode 100644 index 237d1f90e7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_header.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -
- {% include '@SyliusAdmin/Common/Label/shipmentState.html.twig' with {'data': shipment.state} %} -
- diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_resendConfirmationEmailButton.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_resendConfirmationEmailButton.html.twig deleted file mode 100644 index 415fe1fd2b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_resendConfirmationEmailButton.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -{% if shipment.state == shipped %} - {% set path = path('sylius_admin_shipment_resend_confirmation_email', {'id': shipment.id, '_csrf_token': csrf_token(shipment.id)}) %} - - {{ 'sylius.ui.resend_the_shipment_confirmation_email'|trans }} - -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_shipTransition.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_shipTransition.html.twig deleted file mode 100644 index a344a6d705..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_shipTransition.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% if sylius_sm_can(shipment, 'sylius_shipment', 'ship') %} - {{ render(path('sylius_admin_partial_shipment_ship', {'orderId': order.id, 'id': shipment.id})) }} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_showButton.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_showButton.html.twig deleted file mode 100644 index 94351a7120..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_showButton.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% if shipment.state != cart %} - - {{ 'sylius.ui.show'|trans }} - -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_tracking.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_tracking.html.twig deleted file mode 100644 index 8851981c12..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Shipment/_tracking.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -{% if shipment.tracking is not empty %} -
- {{ 'sylius.ui.tracking_code'|trans|upper }} -

{{ shipment.tracking }}

-
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_item.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_item.html.twig deleted file mode 100644 index 575e75f8a6..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_item.html.twig +++ /dev/null @@ -1,50 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} -{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} -{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} -{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} - -{% set variant = item.variant %} -{% set product = variant.product %} - -{% set aggregatedUnitPromotionAdjustments = item.getAdjustmentsTotalRecursively(unitPromotionAdjustment) + item.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} -{% set subtotal = (item.unitPrice * item.quantity) + aggregatedUnitPromotionAdjustments %} - -{% set taxIncluded = sylius_admin_order_unit_tax_included(item) %} -{% set taxExcluded = sylius_admin_order_unit_tax_excluded(item) %} - - - - {% include '@SyliusAdmin/Product/_info.html.twig' %} - - - {{ money.format(item.unitPrice, order.currencyCode) }} - - - {{ money.format(item.units.first.adjustmentsTotal(unitPromotionAdjustment), order.currencyCode) }} - - - ~ {{ money.format(item.units.first.adjustmentsTotal(orderPromotionAdjustment), order.currencyCode) }} - - - {{ money.format(item.fullDiscountedUnitPrice, order.currencyCode) }} - - - {{ item.quantity }} - - - {{ money.format(subtotal, order.currencyCode) }} - - -
{{ money.format(taxExcluded, order.currencyCode) }}
-
-
{{ money.format(taxIncluded, order.currencyCode) }} -
- ({{ 'sylius.ui.included_in_price'|trans }}) -
- - - {{ money.format(item.total, order.currencyCode) }} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_totals.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_totals.html.twig deleted file mode 100644 index 4666b39244..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_totals.html.twig +++ /dev/null @@ -1,85 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -{% set orderShippingPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT') %} -{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} -{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} - -{% set orderShippingPromotions = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderShippingPromotionAdjustment)) %} - - - - - {{ 'sylius.ui.tax_total'|trans }}: - {{ money.format(order.taxTotal, order.currencyCode) }} - - - {{ 'sylius.ui.items_total'|trans }}: - {{ money.format(order.itemsTotal, order.currencyCode) }} - - - - - {% if not order.adjustments(shippingAdjustment).isEmpty() %} -
-
{{ 'sylius.ui.shipping'|trans }}:
- {% for shipment in order.shipments %} - {% for adjustment in shipment.adjustments(shippingAdjustment) %} -
-
{{ money.format(adjustment.amount, order.currencyCode) }}
-
-
- {{ adjustment.label }}: -
-
-
- {% endfor %} - - {% for adjustment in shipment.adjustments(taxAdjustment) %} -
-
- {{ money.format(adjustment.amount, order.currencyCode) }} - {% if adjustment.isNeutral %} - ({{ 'sylius.ui.included_in_price'|trans }}) - {% endif %} -
-
-
- {{ adjustment.label }}: -
-
-
- {% endfor %} - {% endfor %} -
- {% else %} -

{{ 'sylius.ui.no_shipping_charges'|trans }}

- {% endif %} - - {% if not orderShippingPromotions is empty %} - -
-
{{ 'sylius.ui.shipping_discount'|trans }}:
- {% for label, amount in orderShippingPromotions %} -
-
- {{ money.format(amount, order.currencyCode) }} -
-
- {% endfor %} -
- - {% endif %} - - {{ 'sylius.ui.shipping_total'|trans }}: - {{ money.format(order.shippingTotal, order.currencyCode) }} - - - -{% include '@SyliusAdmin/Order/Show/Summary/_totalsPromotions.html.twig' %} - - - - {{ 'sylius.ui.order_total'|trans }}: - {{ money.format(order.total, order.currencyCode) }} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_totalsPromotions.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_totalsPromotions.html.twig deleted file mode 100644 index f5e376b2ec..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/Summary/_totalsPromotions.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} -{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} - - - - {% set orderPromotionAdjustments = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderPromotionAdjustment)) %} - {% set unitPromotionAdjustments = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(unitPromotionAdjustment)) %} - {% set promotionAdjustments = orderPromotionAdjustments|merge(unitPromotionAdjustments) %} - {% if not promotionAdjustments is empty %} -
-
{{ 'sylius.ui.promotions'|trans }}:
- {% for label, amount in promotionAdjustments %} -
-
{{ money.format(amount, order.currencyCode) }}
-
{{ label }}:
-
- {% endfor %} -
- {% else %} -

{{ 'sylius.ui.no_promotion'|trans }}.

- {% endif %} - - - {% set orderPromotionTotal = order.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} - {% set unitPromotionTotal = order.getAdjustmentsTotalRecursively(unitPromotionAdjustment) %} - {{ 'sylius.ui.promotion_total'|trans }}: - {{ money.format(orderPromotionTotal + unitPromotionTotal, order.currencyCode) }} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_addresses.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_addresses.html.twig deleted file mode 100644 index e0a7a15abf..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_addresses.html.twig +++ /dev/null @@ -1,21 +0,0 @@ -{% if order.billingAddress is not null %} -

- {{ 'sylius.ui.billing_address'|trans }} -

-
- {% include '@SyliusAdmin/Common/_address.html.twig' with {'address': order.billingAddress} %} -
-{% endif %} -{% if order.shippingAddress is not null %} -

- {{ 'sylius.ui.shipping_address'|trans }} -

-
- {% include '@SyliusAdmin/Common/_address.html.twig' with {'address': order.shippingAddress} %} -
-{% endif %} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_breadcrumb.html.twig deleted file mode 100644 index 9884c0f086..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_breadcrumb.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.orders'|trans, url: path('sylius_admin_order_index') }, - { label: '#'~order.number } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_content.html.twig deleted file mode 100644 index 7a9b30515f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_content.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-
- {{ sylius_template_event('sylius.admin.order.show.summary', _context) }} -
-
- {{ sylius_template_event('sylius.admin.order.show.sidebar', _context) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_customer.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_customer.html.twig deleted file mode 100644 index d999a7937c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_customer.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusAdmin/Customer/_info.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_header.html.twig deleted file mode 100644 index b71c5fae8f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_header.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -

- -
- {{ 'sylius.ui.order'|trans }} #{{ order.number }} -
-
- {{ sylius_template_event('sylius.admin.order.show.header_items', _context) }} -
-
-
-

diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_headerItems.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_headerItems.html.twig deleted file mode 100644 index fc1a79f57c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_headerItems.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -
- {{ order.checkoutCompletedAt|format_datetime }} -
-
- {% include [('@SyliusAdmin/Order/Label/State' ~ '/' ~ order.state ~ '.html.twig'), '@SyliusUi/Label/_default.html.twig'] with {'value': ('sylius.ui.' ~ order.state)|trans} %} -
-
- {{ order.currencyCode }} -
-
- {{ flags.fromLocaleCode(order.localeCode) }}{{ order.localeCode|sylius_locale_name }} -
-
- {{ 'sylius.ui.purchased_from'|trans }} - {% include '@SyliusAdmin/Common/_channel.html.twig' with {'channel': order.channel} %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_headerWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_headerWidget.html.twig deleted file mode 100644 index eea8007467..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_headerWidget.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-
- {% include '@SyliusAdmin/Order/Show/_header.html.twig' %} -
- - {% set menu = knp_menu_get('sylius.admin.order.show', [], {'order': order}) %} - {{ knp_menu_render(menu, {'template': '@SyliusUi/Menu/top.html.twig'}) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_notes.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_notes.html.twig deleted file mode 100644 index 18938f631d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_notes.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% if order.notes is not null %} -

- {{ 'sylius.ui.notes'|trans }} -

-
- {{ order.notes }} -
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_payment.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_payment.html.twig deleted file mode 100644 index de2770050c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_payment.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% import '@SyliusUi/Macro/labels.html.twig' as label %} - -
- {{ sylius_template_event('sylius.admin.order.show.payment_content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_payments.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_payments.html.twig deleted file mode 100644 index e108b8a52c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_payments.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% if order.hasPayments %} -
- {{ sylius_template_event('sylius.admin.order.show.payments_content', _context) }} -
-{% else %} -
- - {{ 'sylius.ui.no_payments'|trans }} - -
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_paymentsContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_paymentsContent.html.twig deleted file mode 100644 index 369ff62432..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_paymentsContent.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% include '@SyliusAdmin/Order/Label/PaymentState/' ~ order.paymentState ~ '.html.twig' with { 'value': 'sylius.ui.' ~ order.paymentState, 'attached': true } %} -

{{ 'sylius.ui.payments'|trans }}

-
- {% for payment in order.payments %} - {% include '@SyliusAdmin/Order/Show/_payment.html.twig' %} - {% endfor %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_resendEmail.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_resendEmail.html.twig deleted file mode 100644 index a8f1811a03..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_resendEmail.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% if order.state in sylius_order_states_that_allows_to_resend_order_confirmation_email %} -
- {% set path = path('sylius_admin_order_resend_confirmation_email', {'id': order.id, '_csrf_token': csrf_token(order.id)}) %} - - {{ 'sylius.ui.resend_the_order_confirmation_email'|trans }} - -
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipment.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipment.html.twig deleted file mode 100644 index 9ad9108d45..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipment.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% import '@SyliusUi/Macro/labels.html.twig' as label %} - -{% set cart = constant('Sylius\\Component\\Shipping\\Model\\Shipment::STATE_CART') %} -{% set shipped = constant('Sylius\\Component\\Shipping\\Model\\Shipment::STATE_SHIPPED') %} - -
- {{ sylius_template_event('sylius.admin.order.show.shipment_content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipments.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipments.html.twig deleted file mode 100644 index 6d70c719ca..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipments.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -
- {% include '@SyliusAdmin/Order/Label/ShippingState/' ~ order.shippingState ~ '.html.twig' with { 'value': 'sylius.ui.' ~ order.shippingState, 'attached': true } %} - {{ sylius_template_event('sylius.admin.order.show.shipments_content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipmentsContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipmentsContent.html.twig deleted file mode 100644 index db8468c751..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_shipmentsContent.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% if order.hasShipments %} -

{{ 'sylius.ui.shipments'|trans }}

-
- {% for shipment in order.shipments %} - {% include '@SyliusAdmin/Order/Show/_shipment.html.twig' %} - {% endfor %} -
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_summary.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_summary.html.twig deleted file mode 100644 index ef491d3475..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_summary.html.twig +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - {% for item in order.items %} - {% include '@SyliusAdmin/Order/Show/Summary/_item.html.twig' %} - {% endfor %} - - - {% include '@SyliusAdmin/Order/Show/Summary/_totals.html.twig' %} - -
{{ 'sylius.ui.order_item_product'|trans }}{{ 'sylius.ui.unit_price'|trans }}{{ 'sylius.ui.unit_discount'|trans }}{{ 'sylius.ui.distributed_order_discount'|trans }}{{ 'sylius.ui.discounted_unit_price'|trans }}{{ 'sylius.ui.quantity'|trans }}{{ 'sylius.ui.subtotal'|trans }}{{ 'sylius.ui.tax'|trans }}{{ 'sylius.ui.total'|trans }}
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_summaryWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_summaryWidget.html.twig deleted file mode 100644 index 7aae5fd0ca..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Show/_summaryWidget.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -
- {% include '@SyliusAdmin/Order/Show/_summary.html.twig' %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_actions.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_actions.html.twig deleted file mode 100644 index 0b21b92b94..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_actions.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ 'sylius.ui.return'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_breadcrumb.html.twig deleted file mode 100644 index 10cf145a35..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_breadcrumb.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.orders'|trans, url: path('sylius_admin_order_index') }, - { label: '#'~order.number, url: path('sylius_admin_order_show', {'id': order.id}) }, - { label: 'sylius.ui.edit'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_content.html.twig deleted file mode 100644 index 515c1d53ed..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_content.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} - -{{ form_start(form, {'action': path('sylius_admin_order_update', {'id': order.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} -
- - -
-

{{ 'sylius.ui.shipping_address'|trans }}

- {% include '@SyliusAdmin/Common/Form/_address.html.twig' with {'form': form.shippingAddress} %} -
- -
-

{{ 'sylius.ui.billing_address'|trans }}

- {% include '@SyliusAdmin/Common/Form/_address.html.twig' with {'form': form.billingAddress} %} -
- - {{ sylius_template_event('sylius.admin.order.update.form', {'resource': resource}) }} - - {{ form_row(form._token) }} - {% include '@SyliusUi/Form/Buttons/_update.html.twig' with {'paths': {'cancel': sylius_generate_redirect_path(path('sylius_admin_order_index'))}} %} -
-{{ form_end(form, {'render_rest': false}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_header.html.twig deleted file mode 100644 index e7064de94b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Update/_header.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-
- {% include '@SyliusAdmin/Order/Show/_header.html.twig' %} -
-
- {% include '@SyliusAdmin/Order/Update/_actions.html.twig' %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/history.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/history.html.twig deleted file mode 100644 index 9b4778e2f1..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/history.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% import '@SyliusUi/Macro/labels.html.twig' as label %} - -{% block title %}{{ 'sylius.ui.order'|trans }} #{{ order.number }} - {{ 'sylius.ui.order_history'|trans }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.order.history.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/show.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/show.html.twig deleted file mode 100644 index c9506d5398..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/show.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% block title %}{{ 'sylius.ui.order'|trans ~' #'~ order.number }} {{ parent() }}{% endblock %} - -{% set customer = order.customer %} - -{% block content %} - {{ sylius_template_event('sylius.admin.order.show.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/update.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Order/update.html.twig deleted file mode 100644 index d031659506..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/update.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} -{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} - -{% block title %}{{ 'sylius.ui.edit_order'|trans ~' #'~ order.number }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.order.update.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/Gateways/paymentGateways.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/Gateways/paymentGateways.html.twig deleted file mode 100644 index e5235dd3c2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/Gateways/paymentGateways.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% for name, gateway in gatewayFactories %} - - {{ gateway|trans }} - -{% endfor %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/Grid/Action/create.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/Grid/Action/create.html.twig deleted file mode 100644 index bed4e3c859..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/Grid/Action/create.html.twig +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/_form.html.twig deleted file mode 100644 index bf81276fb2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PaymentMethod/_form.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -{{ form_errors(form) }} - -
-

{{ 'sylius.ui.details'|trans }}

- {{ form_errors(form) }} - -
- {{ form_row(form.code) }} - {{ form_row(form.position) }} -
- {{ form_row(form.enabled) }} - {{ form_row(form.channels) }} -
- -
-

{{ 'sylius.ui.gateway_configuration'|trans }}

- - {% if resource.gatewayConfig.factoryName == 'stripe_checkout' %} -
- - -
-
- {{ 'sylius.ui.gateway.no_sca_support_notice'|trans }} -
-
-
- {% endif %} - - {{ form_row(form.gatewayConfig.factoryName) }} - {% if form.gatewayConfig.config is defined %} - {% for field in form.gatewayConfig.config %} - {% if loop.index is odd and not loop.last %}
{% endif %} - {{ form_row(field) }} - {% if loop.index is even %}
{% endif %} - {% endfor %} - {% endif %} -
- -
- {% for locale, translationForm in form.translations %} -
- - {{ flags.fromLocaleCode(locale) }} {{ locale|sylius_locale_name }} -
-
- {{ form_row(translationForm.name) }} - {{ form_row(translationForm.description) }} -
-

- {{ 'sylius.ui.the_instructions_below_will_be_displayed_to_the_customer'|trans }}. -

-
- {{ form_row(translationForm.instructions) }} -
- {% endfor %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributeChoice.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributeChoice.html.twig deleted file mode 100644 index 838cf47747..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributeChoice.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -
- {{ form_widget(form, {'attr': {'class': 'ui fluid search dropdown', 'id': 'sylius_product_attribute_choice'}}) }} - -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributeValues.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributeValues.html.twig deleted file mode 100644 index 7a8b3ecf78..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributeValues.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{% import _self as self %} -{% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -{% set subject = metadata.name|replace({'_attribute': ''}) %} -{% for code, localeCodes in forms %} -
-
- {{ (localeCodes|first).vars.label }} -
- -
-
-
- {% for localeCode, form in localeCodes %} -
- {% set id = form.vars.label|replace({' ': '_'})|lower %} -
-
- -
-
- {% if 'type_checkbox' in form.vars.cache_key %} -
- {{ self.formField(form, count, id, '', subject, metadata.applicationName) }} - -
- {% else %} - {{ self.formField(form, count, id, '', subject, metadata.applicationName) }} - {% endif %} -
-
- {% if localeCode %} - {{ 'sylius.ui.apply_to_all'|trans }} - {% endif %} -
-
- - - {% set count = count + 1 %} -
- {% endfor %} -
-
-{% endfor %} - -{% macro formField(item, count, id, prefix, subject, applicationName) %} - {% from _self import formField %} - {% if item.children|length > 0 %} - {% set prefix = prefix~'_'~item.vars.name %} - {% for child in item.children %} - {{ formField(child, count, id, prefix, subject, applicationName) }} - {% endfor %} - {% elseif item.vars.name != '_token' %} - {% set namePrefix = prefix|replace({'_': ']['}) %} - {% set dataName = applicationName~'_'~subject~'[attributes]['~count~namePrefix~']['~item.vars.name~']' %} - {% if item.vars.multiple is defined and item.vars.multiple %} - {% set dataName = dataName~'[]' %} - {% endif %} - - {{ form_widget(item, {'id': id, 'attr': {'data-name': dataName }}) }} - {% endif %} -{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributesCollection.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributesCollection.html.twig deleted file mode 100644 index 3c72f4876f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Attribute/attributesCollection.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{% extends '@SyliusAdmin/Form/theme.html.twig' %} - -{% block collection_widget -%} - {% import _self as self %} - -
- {% set attributes = {} %} - - {% for child in form %} - {% set code = child.vars.data.attribute.code %} - - {% if attributes[code] is not defined %} - {% set attributes = attributes|merge({ (code): [] }) %} - {% endif %} - - {% set attributes = attributes|merge({ (code): attributes[code]|merge([child]) }) %} - {% endfor %} - - {% for key, attribute in attributes %} -
-
- {{ attribute[0].value.vars.label }} -
- -
-
-
- {% for child in attribute %} - {{ self.collection_item(child) }} - {% endfor %} -
-
- {% endfor %} -
-{%- endblock collection_widget %} - -{% macro collection_item(form) %} - {% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -
-
-
- -
-
-
- {{ form_widget(form.value) }} -
-
-
- {% if form.localeCode.vars.value %} - {{ 'sylius.ui.apply_to_all'|trans }} - {% endif %} -
-
- {{ form_errors(form.value) }} -
-
- - -
-{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Action/generateVariants.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Action/generateVariants.html.twig deleted file mode 100644 index 86a31bcc22..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Action/generateVariants.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} - -{% set path = options.link.url|default(path('sylius_admin_product_variant_generate', {'productId': options.product.id})) %} - -{% if options.product.options is not empty %} - {{ buttons.default(path, 'sylius.ui.generate', null, 'random') }} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Action/updatePositions.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Action/updatePositions.html.twig deleted file mode 100644 index 13c394b9c7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Action/updatePositions.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
- - - -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/image.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/image.html.twig deleted file mode 100644 index e7f0cab753..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/image.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusAdmin/Product/_mainImage.html.twig' with {'product': data} %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/mainTaxon.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/mainTaxon.html.twig deleted file mode 100644 index 52dac3023e..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/mainTaxon.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% if data is not null %}{{ data.name }}{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/name.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/name.html.twig deleted file mode 100644 index c123f46d1b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/name.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% if data is not null %} - {{ data }} -{% else %} - {% include '@SyliusAdmin/Common/_missingTranslation.html.twig' %} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/position.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/position.html.twig deleted file mode 100644 index 00eb4617b3..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Grid/Field/position.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusAdmin/Product/_position.html.twig' with {'product': data, 'taxonId': app.request.get('taxonId')} %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Content/_taxonTree.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Content/_taxonTree.html.twig deleted file mode 100644 index 46028df1bf..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Content/_taxonTree.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ render(path('sylius_admin_partial_taxon_tree', {'template': '@SyliusAdmin/Taxon/_treeWithoutButtons.html.twig'})) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Header/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Header/_breadcrumb.html.twig deleted file mode 100644 index 8c0cb4513d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Header/_breadcrumb.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include configuration.vars.templates.breadcrumb|default('@SyliusAdmin/Product/Index/_breadcrumb.html.twig') %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Header/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Header/_content.html.twig deleted file mode 100644 index 75b2a62a37..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/Header/_content.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} -{{ headers.default(header|trans, configuration.vars.icon|default('cube'), configuration.vars.subheader|default('sylius.ui.manage_your_product_catalog')|trans) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_breadcrumb.html.twig deleted file mode 100644 index 9848f7783b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_breadcrumb.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% if taxon is defined %} - {% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index') }, - { label: taxon.name }, - ] - %} -{% else %} - {% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans }, - ] - %} -{% endif %} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_content.html.twig deleted file mode 100644 index cdf0664d81..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_content.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-
- {{ sylius_template_event('sylius.admin.product.index.content.sidebar', _context) }} -
-
- {{ sylius_template_event('sylius.admin.product.index.content.main', _context) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_header.html.twig deleted file mode 100644 index 989ad9a85f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_header.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% if app.request.attributes.get('taxonId') is not null %} - {{ render(url('sylius_admin_partial_taxon_show', { - 'id': app.request.attributes.get('taxonId'), - 'template': '@SyliusAdmin/Product/Index/_taxonHeader.html.twig', - 'vars': configuration.vars - })) }} -{% else %} -
- {{ sylius_template_event('sylius.admin.product.index.header', _context) }} -
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_headerWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_headerWidget.html.twig deleted file mode 100644 index 86ba48fea7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_headerWidget.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -
- {% include '@SyliusAdmin/Product/Index/_header.html.twig' %} - {% include '@SyliusAdmin/Crud/Index/_actions.html.twig' %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_taxonHeader.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_taxonHeader.html.twig deleted file mode 100644 index ec2445ea57..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Index/_taxonHeader.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -
- {{ headers.default(taxon.name, configuration.vars.icon|default('cube'), configuration.vars.subheader|default('sylius.ui.manage_your_product_catalog')|trans) }} - - {% include configuration.vars.templates.breadcrumb|default('@SyliusAdmin/Product/Index/_breadcrumb.html.twig') %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/boolean.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/boolean.html.twig deleted file mode 100644 index c94c46d0b1..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/boolean.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% extends '@SyliusAttribute/Types/checkbox.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/date.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/date.html.twig deleted file mode 100644 index 54f544308c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/date.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% extends '@SyliusAttribute/Types/date.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/datetime.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/datetime.html.twig deleted file mode 100644 index a322e7084a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/datetime.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% extends '@SyliusAttribute/Types/datetime.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/default.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/default.html.twig deleted file mode 100644 index 77ca5c3c21..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/default.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% extends '@SyliusAttribute/Types/default.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/integer.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/integer.html.twig deleted file mode 100644 index e8bd6cd9a6..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/integer.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ attribute.value }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/percent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/percent.html.twig deleted file mode 100644 index 81bdd9e113..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/percent.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% extends '@SyliusAttribute/Types/percent.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/select.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/select.html.twig deleted file mode 100644 index d313e54beb..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/select.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -{% if attribute.value is not null %} - {% set values = attribute.attribute.configuration.choices %} - {% if attribute.value is iterable %} - {% for value in attribute.value %} - {% if locale in values[value]|keys %} - {{ values[value][locale]|default(fallbackLocale) }}{% if loop.last == false %},{% endif %} - {% endif %} - {% endfor %} - {% else %} - {% if values[attribute.value][locale] is not empty %} - {{ values[attribute.value][locale] }} - {% elseif values[attribute.value][fallbackLocale] is not empty %} - {{ values[attribute.value][fallbackLocale] }} - {% endif %} - {% endif %} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/text.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/text.html.twig deleted file mode 100644 index dfd0afc501..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/Types/text.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% extends '@SyliusAttribute/Types/textarea.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_button.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_button.html.twig deleted file mode 100644 index b7a80133d4..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_button.html.twig +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_editButton.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_editButton.html.twig deleted file mode 100644 index cf655288e3..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_editButton.html.twig +++ /dev/null @@ -1,6 +0,0 @@ - - - - {{ 'sylius.ui.edit'|trans }} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_item.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_item.html.twig deleted file mode 100644 index 51b8c71303..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_item.html.twig +++ /dev/null @@ -1,17 +0,0 @@ - -
-
-
- {% if variant.hasImages %} - {% include '@SyliusAdmin/Product/_mainImage.html.twig' with {'product': variant, 'filter': 'sylius_admin_product_large_thumbnail'} %} - {% else %} - {% include '@SyliusAdmin/Product/_mainImage.html.twig' with {'product': product, 'filter': 'sylius_admin_product_large_thumbnail'} %} - {% endif %} -
-
-
{{ variant.name }}
- {{ variant.code }} -
-
-
- diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_optionValues.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_optionValues.html.twig deleted file mode 100644 index 453eb2c893..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_optionValues.html.twig +++ /dev/null @@ -1,5 +0,0 @@ - - {% for optionValue in variant.optionValues %} -
{{ optionValue.option.name }}: {{ optionValue.value }}
- {% endfor %} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_shipping.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_shipping.html.twig deleted file mode 100644 index 9445fc2911..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_shipping.html.twig +++ /dev/null @@ -1,7 +0,0 @@ - - {% if variant.shippingRequired %} - {{ 'sylius.ui.shipping_required'|trans }} - {% else %} - {{ 'sylius.ui.shipping_not_required'|trans }} - {% endif %} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_stock.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_stock.html.twig deleted file mode 100644 index 1d0aa19407..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_stock.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ variant.onHand }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_taxCategory.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_taxCategory.html.twig deleted file mode 100644 index 56a39312fa..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_taxCategory.html.twig +++ /dev/null @@ -1,7 +0,0 @@ - - {% if variant.taxCategory %} - {{ variant.taxCategory }} - {% else %} -
-
- {% endif %} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_tracking.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_tracking.html.twig deleted file mode 100644 index f280933065..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/VariantItem/_tracking.html.twig +++ /dev/null @@ -1,7 +0,0 @@ - - {% if variant.tracked %} - {{ 'sylius.ui.tracked'|trans }} - {% else %} - {{ 'sylius.ui.not_tracked'|trans }} - {% endif %} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_appliedPromotions.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_appliedPromotions.html.twig deleted file mode 100644 index 35c2c16b1f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_appliedPromotions.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{% if channelPricing.appliedPromotions is empty %} - - -{% else %} - - - -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_associations.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_associations.html.twig deleted file mode 100644 index 1c5f899d9b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_associations.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -
-

{{ 'sylius.ui.associations'|trans }}

-
- {% if product.associations is not empty %} - {% for association in product.associations %} - {{ association.type.name }}: -
    - {% for associatedProduct in association.associatedProducts %} -
  • {{ associatedProduct.name }}
  • - {% endfor %} -
- {% endfor %} - {% else %} - {{ 'sylius.ui.no_associations_to_display'|trans }} - {% endif %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_attributes.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_attributes.html.twig deleted file mode 100644 index acf0e1b43c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_attributes.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -
-

{{ 'sylius.ui.attributes'|trans }}

-
- - {% for locale in setLocales %} - {% set data_tab = (locale is not null ? locale|sylius_locale_name : 'non-translatable') %} -
- - - {% for attributeValue in product.attributes|filter(attributeValue => attributeValue.localeCode == locale) %} - - - - - {% endfor %} - -
- {{ attributeValue.name }} - - {% include [ - '@SyliusAdmin/Product/Show/Types/'~attributeValue.type~'.html.twig', - '@SyliusAttribute/Types/'~attributeValue.type~'.html.twig', - '@SyliusAdmin/Product/Show/Types/default.html.twig' - ] with { - 'attribute': attributeValue, - 'locale': configuration.request.locale, - 'fallbackLocale': configuration.request.defaultLocale - } %} -
-
- {% endfor %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_breadcrumb.html.twig deleted file mode 100644 index 203ca9045c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_breadcrumb.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index') }, - { label: resource.name|default(resource.code|default(resource.id)) } -] %} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_configurableProduct.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_configurableProduct.html.twig deleted file mode 100644 index eaf0ac8929..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_configurableProduct.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{% include '@SyliusAdmin/Product/Show/_header.html.twig' %} - -
-
- {% include '@SyliusAdmin/Product/Show/_taxonomy.html.twig' %} -
-
- {% include '@SyliusAdmin/Product/Show/_options.html.twig' %} -
-
- -{% include '@SyliusAdmin/Product/Show/_media.html.twig' %} - -{% include '@SyliusAdmin/Product/Show/_moreDetails.html.twig' %} - -
-
- {% include '@SyliusAdmin/Product/Show/_attributes.html.twig' %} -
-
- {% include '@SyliusAdmin/Product/Show/_associations.html.twig' %} -
-
- - -{{ sylius_template_event('sylius.admin.configurable_product.show', _context) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_details.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_details.html.twig deleted file mode 100644 index 5a5a356e61..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_details.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -
-

{{ 'sylius.ui.details'|trans }}

-
-
- {{ sylius_template_event('sylius.admin.simple_product.show.details_content', _context) }} -
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_detailsLabels.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_detailsLabels.html.twig deleted file mode 100644 index 92f5fb936f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_detailsLabels.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -{% if product.enabled %} - {{ 'sylius.ui.enabled'|trans }} -{% else %} - {{ 'sylius.ui.disabled'|trans }} -{% endif %} - -{% if product.variants.first.tracked %} - {{ 'sylius.ui.tracked'|trans }} -{% else %} - {{ 'sylius.ui.not_tracked'|trans }} -{% endif %} - -{% if product.variants.first.shippingRequired %} - {{ 'sylius.ui.shipping_required'|trans }} -{% else %} - {{ 'sylius.ui.shipping_not_required'|trans }} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_detailsTable.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_detailsTable.html.twig deleted file mode 100644 index 13144a3527..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_detailsTable.html.twig +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - -
{{ 'sylius.ui.code'|trans }}{{ product.code }}
{{ 'sylius.ui.channels'|trans }} - {% for channel in product.channels %} -
- - {{ channel }} -
- {% endfor %} -
{{ 'sylius.ui.current_stock'|trans }}{{ product.variants.first.onHand }}
{{ 'sylius.ui.tax_category'|trans }}{{ product.variants.first.taxCategory }}
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_header.html.twig deleted file mode 100644 index 3823478ae0..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_header.html.twig +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_imageVariants.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_imageVariants.html.twig deleted file mode 100644 index eed782bd78..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_imageVariants.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -
-{% if product.getVariantSelectionMethod() == 'match' %} - {% for variant in image.productVariants %} -
- {% endfor %} -{% else %} - {% for variant in image.productVariants %} -
- {% endfor %} -{% endif %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_mainImage.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_mainImage.html.twig deleted file mode 100644 index 4a44de1f2b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_mainImage.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if product.imagesByType('thumbnail') is not empty %} - {% set path = product.imagesByType('thumbnail').first.path|imagine_filter(filter|default('sylius_admin_product_thumbnail')) %} -{% elseif product.images.first %} - {% set path = product.images.first.path|imagine_filter(filter|default('sylius_admin_product_thumbnail')) %} -{% else %} - {% set path = asset('build/admin/images/200x200.png', 'admin') %} -{% endif %} - -{{ product.name }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_media.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_media.html.twig deleted file mode 100644 index da50ea8550..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_media.html.twig +++ /dev/null @@ -1,23 +0,0 @@ -
-
- - {{ 'sylius.ui.media'|trans }} -
-
- {% if product.images|length >= 1 %} -
- {% for image in product.images %} - {% set path = image.path is not null ? image.path|imagine_filter('sylius_admin_product_small_thumbnail') : asset('build/admin/images/200x200.png', 'admin') %} -
- {% if product.isConfigurable() and product.variants|length > 0 %} - {% include '@SyliusAdmin/Product/Show/_imageVariants.html.twig' %} - {% endif %} - - {{ product.name }} - -
- {% endfor %} -
- {% endif %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_moreDetails.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_moreDetails.html.twig deleted file mode 100644 index dd1def95e5..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_moreDetails.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% import '@SyliusUi/Macro/flags.html.twig' as flags %} - -
- {% for translation in product.translations %} -
- - {{ flags.fromLocaleCode(translation.locale) }} {{ translation.locale|sylius_locale_name }} -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{ 'sylius.ui.name'|trans }}{{ translation.name }}
{{ 'sylius.ui.slug'|trans }}{{ translation.slug }}
{{ 'sylius.ui.description'|trans }}{{ translation.description|nl2br }}
{{ 'sylius.ui.meta_keywords'|trans }}{{ translation.metaKeywords }}
{{ 'sylius.ui.meta_description'|trans }}{{ translation.metaDescription }}
{{ 'sylius.ui.short_description'|trans }}{{ translation.shortDescription }}
-
- {% endfor %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_options.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_options.html.twig deleted file mode 100644 index 37713bdb12..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_options.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -
-

{{ 'sylius.ui.options'|trans }}

-
-
-
    - {% for option in product.options %} -
  • {{ option }}
  • - {% endfor %} -
-
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_pricing.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_pricing.html.twig deleted file mode 100644 index 948bd60219..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_pricing.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} -
-

{{ 'sylius.ui.pricing'|trans }}

-
- - - - - - - - - - - - - {% for channelPricing in product.variants.first.channelPricings %} - {% if product.channels.first != false %} - - - - - - {% include '@SyliusAdmin/Product/Show/_appliedPromotions.html.twig' %} - - - {% endif %} - {% endfor %} - -
{{ 'sylius.ui.channels'|trans }}{{ 'sylius.ui.price'|trans }}{{ 'sylius.ui.original_price'|trans }}{{ 'sylius.ui.lowest_price_before_discount'|trans }}{{ 'sylius.ui.discounted_by'|trans }}{{ 'sylius.ui.history'|trans }}
- {{ channelPricing.channelCode|sylius_channel_name }} - {{ money.format(channelPricing.price, product.channels.first.baseCurrency) }}{{ channelPricing.originalPrice ? money.format(channelPricing.originalPrice, product.channels.first.baseCurrency) : '-' }}{{ channelPricing.lowestPriceBeforeDiscount ? money.format(channelPricing.lowestPriceBeforeDiscount, product.channels.first.baseCurrency) : '-' }} - - - {{ 'sylius.ui.show'|trans }} - -
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_shipping.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_shipping.html.twig deleted file mode 100644 index c55924dba6..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_shipping.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -
-

{{ 'sylius.ui.shipping'|trans }}

-
- - - - - - - - - - - - - - - - - - - - - - - -
{{ 'sylius.ui.shipping_category'|trans }}{{ product.variants.first.shippingCategory is not empty ? product.variants.first.shippingCategory : '-' }}
{{ 'sylius.ui.width'|trans }}{{ product.variants.first.width is not empty ? product.variants.first.width : '-' }}
{{ 'sylius.ui.height'|trans }}{{ product.variants.first.height is not empty ? product.variants.first.height : '-' }}
{{ 'sylius.ui.depth'|trans }}{{ product.variants.first.depth is not empty ? product.variants.first.depth : '-' }}
{{ 'sylius.ui.weight'|trans }}{{ product.variants.first.weight is not empty ? product.variants.first.weight : '-' }}
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_simpleProduct.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_simpleProduct.html.twig deleted file mode 100644 index d9ab73da7d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_simpleProduct.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{% include '@SyliusAdmin/Product/Show/_header.html.twig' %} - -
-
- {{ sylius_template_event('sylius.admin.simple_product.show.details', _context) }} - - {{ sylius_template_event('sylius.admin.simple_product.show.taxonomy', _context) }} -
-
- {{ sylius_template_event('sylius.admin.simple_product.show.pricing', _context) }} - - {{ sylius_template_event('sylius.admin.simple_product.show.shipping', _context) }} -
-
- -{{ sylius_template_event('sylius.admin.simple_product.show.media', _context) }} - - -{{ sylius_template_event('sylius.admin.simple_product.show.more_details', _context) }} - - -
-
- {{ sylius_template_event('sylius.admin.simple_product.show.attributes', _context) }} -
-
- {{ sylius_template_event('sylius.admin.simple_product.show.associations', _context) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_taxonomy.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_taxonomy.html.twig deleted file mode 100644 index 8598f71a83..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_taxonomy.html.twig +++ /dev/null @@ -1,25 +0,0 @@ -
-

{{ 'sylius.ui.taxonomy'|trans }}

-
- - - {% if product.mainTaxon != null %} - - - - - {% endif %} - - - - - -
{{ 'sylius.ui.main_taxon'|trans }}{{ product.mainTaxon.getFullName }}
{{ 'sylius.ui.product_taxons'|trans }} -
    - {% for productTaxon in product.productTaxons %} -
  • {{ productTaxon.getTaxon.getFullName }}
  • - {% endfor %} -
-
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContent.html.twig deleted file mode 100644 index 612b69581c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContent.html.twig +++ /dev/null @@ -1,9 +0,0 @@ - - -
-
- {{ sylius_template_event('sylius.admin.configurable_product.show.variant_content', _context) }} -
-
- - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContentPricing.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContentPricing.html.twig deleted file mode 100644 index 16184f88ee..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContentPricing.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -
-
-
- {{ 'sylius.ui.pricing'|trans }} -
- - - - - - - - - - - {% set currencies = sylius_channels_currencies() %} - {% for channelPricing in variant.channelPricings %} - - - - - - {% include '@SyliusAdmin/Product/Show/_appliedPromotions.html.twig' %} - - - {% endfor %} - -
{{ 'sylius.ui.channels'|trans }}{{ 'sylius.ui.price'|trans }}{{ 'sylius.ui.original_price'|trans }}{{ 'sylius.ui.lowest_price_before_discount'|trans }}{{ 'sylius.ui.discounted_by'|trans }}{{ 'sylius.ui.history'|trans }}
- {{ channelPricing.channelCode|sylius_channel_name }} - {{ money.format(channelPricing.price, product.channels.first.baseCurrency) }}{{ channelPricing.originalPrice ? money.format(channelPricing.originalPrice, product.channels.first.baseCurrency) : '-' }}{{ channelPricing.lowestPriceBeforeDiscount ? money.format(channelPricing.lowestPriceBeforeDiscount, product.channels.first.baseCurrency) : '-' }} - - - {{ 'sylius.ui.show'|trans }} - -
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContentShipping.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContentShipping.html.twig deleted file mode 100644 index 04cc40e2c8..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantContentShipping.html.twig +++ /dev/null @@ -1,37 +0,0 @@ -
-
-
- {{ 'sylius.ui.shipping'|trans }} -
- {% if variant.shippingCategory is same as(null) and variant.width is same as(null) and variant.height is same as(null) and variant.depth is same as(null) and variant.weight is same as(null) %} -
-

{{ 'sylius.ui.no_shipping_data'|trans }}

-
- {% else %} - - - - - - - - - - - - - - - - - - - - - - - -
{{ 'sylius.ui.shipping_category'|trans }}{{ variant.shippingCategory }}
{{ 'sylius.ui.width'|trans }}{{ variant.width }}
{{ 'sylius.ui.height'|trans }}{{ variant.height }}
{{ 'sylius.ui.depth'|trans }}{{ variant.depth }}
{{ 'sylius.ui.weight'|trans }}{{ variant.weight }}
- {% endif %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantItem.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantItem.html.twig deleted file mode 100644 index 36e2cb4211..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantItem.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ sylius_template_event('sylius.admin.configurable_product.show.variant_item', _context) }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variants.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variants.html.twig deleted file mode 100644 index 1a1d3e7d9f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variants.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -
-

{{ 'sylius.ui.list_variants'|trans }}

- - {{ sylius_template_event('sylius.admin.product.show.variants_content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantsContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantsContent.html.twig deleted file mode 100644 index 283734f42d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Show/_variantsContent.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -
- - - - - - - - - - - - - - - {% for variant in product.variants %} - {% include '@SyliusAdmin/Product/Show/_variantItem.html.twig' %} - {% include '@SyliusAdmin/Product/Show/_variantContent.html.twig' %} - {% endfor %} - -
{{ 'sylius.ui.name'|trans }}{{ 'sylius.ui.options'|trans }}{{ 'sylius.ui.tracked'|trans }}{{ 'sylius.ui.shipping_required'|trans }}{{ 'sylius.ui.tax_category'|trans }}{{ 'sylius.ui.current_stock'|trans }}{{ 'sylius.ui.actions'|trans }}
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_associations.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_associations.html.twig deleted file mode 100644 index 007a79ef8f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_associations.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -
-

{{ 'sylius.ui.associations'|trans }}

- -
- {% for associationForm in form.associations %} -
- {{- form_label(associationForm) -}} - - {{ form_errors(associationForm) }} -
- {% endfor %} - - {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_associations', 'sylius.admin.product.tab_associations'], {'form': form}) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_attributes.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_attributes.html.twig deleted file mode 100644 index 2be9ffa6f2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_attributes.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{% form_theme form '@SyliusAdmin/Product/Attribute/attributesCollection.html.twig' %} - -
-

{{ 'sylius.ui.attributes'|trans }}

- -
- {{ render(url('sylius_admin_get_product_attributes')) }} -
- {{ form_widget(form.attributes, {'attr': {'translations': form.translations} }) }} -
- - {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_attributes', 'sylius.admin.product.tab_attributes'], {'form': form}) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_details.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_details.html.twig deleted file mode 100644 index 4f7deb2fe9..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_details.html.twig +++ /dev/null @@ -1,68 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationFormWithSlug %} - -
-

{{ 'sylius.ui.details'|trans }}

- -
- {{ form_errors(form) }} - -
-
-
- {{ form_row(form.code) }} - {{ form_row(form.enabled) }} - {% if product.simple %} - {{ form_row(form.variant.shippingRequired) }} - {% else %} - {{ form_row(form.options, {'remote_url': path('sylius_admin_ajax_product_options_by_phrase'), 'load_edit_url': path('sylius_admin_ajax_find_product_options')}) }} - {{ form_row(form.variantSelectionMethod) }} - {% endif %} - - {# Nothing to see here. #} - -
-
-
- {{ form_row(form.channels) }} -
-
- {% if product.simple %} -
-
-

{{ 'sylius.ui.pricing'|trans }}

- {% include "@SyliusAdmin/Product/_channel_pricing.html.twig" with { product: product, variantForm: form.variant } only %} -
-
- {% endif %} - - {{ translationFormWithSlug(form.translations, '@SyliusAdmin/Product/_slugField.html.twig', product) }} - {% if product.simple %} - -
-
-

{{ 'sylius.ui.shipping'|trans }}

-
- {{ form_row(form.variant.shippingCategory) }} - {{ form_row(form.variant.width) }} - {{ form_row(form.variant.height) }} - {{ form_row(form.variant.depth) }} - {{ form_row(form.variant.weight) }} -
-
-
-

{{ 'sylius.ui.taxes'|trans }}

-
- {{ form_row(form.variant.taxCategory) }} -
-
-
- {% endif %} - - {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_details', 'sylius.admin.product.tab_details'], {'form': form}) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_inventory.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_inventory.html.twig deleted file mode 100644 index 6da3b8b4e2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_inventory.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -
- {{ sylius_template_event('sylius.admin.product.tab_inventory_content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_inventoryContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_inventoryContent.html.twig deleted file mode 100644 index 300f40ae76..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_inventoryContent.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -

{{ 'sylius.ui.inventory'|trans }}

-
- {% if product.simple %} - {{ form_row(form.variant.onHand) }} -
- - {{ form_row(form.variant.tracked) }} -
- {{ form_help(form.variant.tracked) }} -
- - {{ form_row(form.variant.version) }} - {% endif %} -
- -{{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_inventory', 'sylius.admin.product.tab_inventory'], {'form': form}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_media.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_media.html.twig deleted file mode 100644 index 9a32fcd3ee..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_media.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% form_theme form '@SyliusAdmin/Form/imagesTheme.html.twig' %} - -
-

{{ 'sylius.ui.media'|trans }}

- -
-
- {{ form_row(form.images, {'label': false}) }} - - {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_media', 'sylius.admin.product.tab_media'], {'form': form}) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_taxonomy.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_taxonomy.html.twig deleted file mode 100644 index 98dba32810..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Tab/_taxonomy.html.twig +++ /dev/null @@ -1,20 +0,0 @@ -
-

{{ 'sylius.ui.taxonomy'|trans }}

- -
- {{ form_row(form.mainTaxon) }} - -

{{ 'sylius.ui.product_taxon'|trans }}

-
- {{ form_widget(form.productTaxons) }} -
-
-
-
- - {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_taxonomy', 'sylius.admin.product.tab_taxonomy'], {'form': form}) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Update/_toolbar.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Update/_toolbar.html.twig deleted file mode 100644 index 4c664137f8..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/Update/_toolbar.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -
- {% set menu = knp_menu_get('sylius.admin.product.update', [], {'product': product}) %} - {{ knp_menu_render(menu, {'template': '@SyliusUi/Menu/top.html.twig'}) }} - {% include '@SyliusAdmin/Product/_showInShopButton.html.twig' %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_channel_pricing.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_channel_pricing.html.twig deleted file mode 100644 index 6d4014a50e..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_channel_pricing.html.twig +++ /dev/null @@ -1,27 +0,0 @@ -
- {{ form_errors(variantForm.channelPricings) }} - - {% for channelCode, channelPricing in variantForm.channelPricings %} - {% if loop.index0 == 0 %} -
- {% else %} -
- {% endif %} - - {% if channelCode not in product.channels|map(channel => channel.code) %} -
- {{ 'sylius.ui.product.product_not_active_in_channel'|trans }} -
- {% endif %} - {{ form_row(channelPricing, {'label': false}) }} -
- {% endfor %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_form.html.twig deleted file mode 100644 index 1b884f8109..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_form.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{% set menu = knp_menu_get('sylius.admin.product_form', [], {'product': product}) %} -{{ knp_menu_render(menu, {'template': '@SyliusAdmin/Product/_menu.html.twig', 'form': form, 'product': product}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_info.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_info.html.twig deleted file mode 100644 index 41c8c0f5f8..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_info.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -
- {% include '@SyliusAdmin/Product/_mainImage.html.twig' with {'product': product, 'filter': 'sylius_admin_product_tiny_thumbnail'} %} -
-
{{ item.productName }}
- - {{ variant.code }} - -
-
-{% if product.hasOptions() %} -
- {% for optionValue in variant.optionValues %} -
- {{ optionValue.value }} -
- {% endfor %} -
-{% elseif item.variantName is not null %} -
-
- {{ item.variantName }} -
-
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_mainImage.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_mainImage.html.twig deleted file mode 100644 index 6fb55dcb60..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_mainImage.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if product.imagesByType('thumbnail') is not empty %} - {% set path = product.imagesByType('thumbnail').first.path|imagine_filter(filter|default('sylius_admin_product_thumbnail')) %} -{% elseif product.images.first %} - {% set path = product.images.first.path|imagine_filter(filter|default('sylius_admin_product_thumbnail')) %} -{% else %} - {% set path = asset('build/admin/images/50x50.png', 'admin') %} -{% endif %} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_menu.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_menu.html.twig deleted file mode 100644 index 8024bb3eb8..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_menu.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% extends 'knp_menu.html.twig' %} - -{% if 'create' in app.request.attributes.get('_route') %} - {% set action = 'create' %} -{% else %} - {% set action = 'update' %} -{% endif %} - -{% block list %} -{% set form = (options.form) %} -
-
- -
-
- {{ form_errors(form) }} -
- {% for item in item.children %} - {% include item.attribute('template') with {'form': form, 'product': options.product} %} - {% endfor %} -
-
-
-{% endblock %} - -{% block item %} - {%- set attributes = item.attributes %} - {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %} - {%- if item.actsLikeFirst %} - {%- set classes = classes|merge(['active']) %} - {%- endif %} - {%- if classes is not empty %} - {%- set attributes = attributes|merge({'class': classes|join(' ')}) %} - {%- endif %} - {{ item.label|trans }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_position.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_position.html.twig deleted file mode 100644 index 44984003e9..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_position.html.twig +++ /dev/null @@ -1,19 +0,0 @@ -{% if taxonId %} - {% for productTaxon in product.productTaxons%} - {% if taxonId == productTaxon.taxon.id %} -
-
- -
-
- {% endif %} - {% endfor %} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_showInShopButton.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_showInShopButton.html.twig deleted file mode 100644 index 37ac161938..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_showInShopButton.html.twig +++ /dev/null @@ -1,54 +0,0 @@ -{% set enabledChannels = product.channels|filter(channel => channel.enabled == true) %} - -{% if sylius_bundle_loaded_checker('SyliusShopBundle') %} - {% if not product.enabled or enabledChannels|length < 1 %} - - - {{ 'sylius.ui.show_product_in_shop_page'|trans }} - - {% elseif enabledChannels|length > 1 %} - - {% else %} - {% for channel in enabledChannels %} - {% set product_translation = sylius_product_translation(product, channel) %} - {% if product_translation is not null %} - {% set url = sylius_channel_url(path('sylius_shop_product_show', {'slug': product_translation.slug, '_locale': product_translation.locale}), channel) %} - {% endif %} - - - - {{ 'sylius.ui.show_product_in_shop_page'|trans }} - - {% endfor %} - {% endif %} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_slugField.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_slugField.html.twig deleted file mode 100644 index 9fde0117f7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/_slugField.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -
- {{ form_label(slugField) }} - {% if slugField.vars.value == null %} - {{ form_widget(slugField, {'attr': {'data-url': path('sylius_admin_ajax_generate_product_slug')}}) }} - {% else %} -
- {{ form_widget(slugField, {'attr': {'readonly': 'readonly', 'data-url': path('sylius_admin_ajax_generate_product_slug')}}) }} - - - -
- {% endif %} - {{ form_errors(slugField) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/index.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/index.html.twig deleted file mode 100644 index f8ed525c45..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/index.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% set definition = resources.definition %} -{% set data = resources.data %} - -{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} - -{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.product.index.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/show.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Product/show.html.twig deleted file mode 100644 index 222d76ec61..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Product/show.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% block title %}{{ 'sylius.ui.show_product'|trans }} | {{ product.name }}{% endblock %} - -{% block content %} - {% if product.variants|length == 1 %} - {% include "@SyliusAdmin/Product/Show/_simpleProduct.html.twig" %} - {% else %} - {% include "@SyliusAdmin/Product/Show/_configurableProduct.html.twig" %} - {% endif %} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAssociationType/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAssociationType/_form.html.twig deleted file mode 100644 index 4ba956087f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAssociationType/_form.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} - -{{ form_errors(form) }} -{{ form_row(form.code) }} -{{ translationForm(form.translations) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/Grid/Action/create.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/Grid/Action/create.html.twig deleted file mode 100644 index 073cb5fa1b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/Grid/Action/create.html.twig +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/Types/attributeTypes.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/Types/attributeTypes.html.twig deleted file mode 100644 index 71d9ee47f3..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/Types/attributeTypes.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% for name, attributeType in types %} - {% set createRouteName = metadata.applicationName~'_admin_'~metadata.name~'_create' %} - - {% set label = 'sylius.form.attribute_type.' ~ attributeType.type %} - {{ label|trans }} - -{% endfor %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/_form.html.twig deleted file mode 100644 index 8bcb726261..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductAttribute/_form.html.twig +++ /dev/null @@ -1,21 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} - -{{ form_errors(form) }} - -
-
- {{ form_row(form.code) }} - {{ form_row(form.position) }} - {{ form_row(form.type) }} -
- {{ form_row(form.translatable) }} -
-{% if form.configuration is defined %} -
-

{{ 'sylius.ui.configuration'|trans }}

- {% for field in form.configuration %} - {{ form_row(field) }} - {% endfor %} -
-{% endif %} -{{ translationForm(form.translations) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductOption/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductOption/_form.html.twig deleted file mode 100644 index 8e93a5c24d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductOption/_form.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} - -
- {{ form_errors(form) }} -
- {{ form_row(form.code) }} - {{ form_row(form.position) }} -
- {{ translationForm(form.translations) }} -
-

{{ 'sylius.ui.values'|trans }}

-{{ form_row(form.values) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/accepted.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/accepted.html.twig deleted file mode 100644 index 895532a778..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/accepted.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/new.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/new.html.twig deleted file mode 100644 index 2539898983..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/new.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/rejected.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/rejected.html.twig deleted file mode 100644 index 9062a2782d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/Label/Status/rejected.html.twig +++ /dev/null @@ -1,4 +0,0 @@ - - - {{ value|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_author.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_author.html.twig deleted file mode 100644 index 74f40445c4..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_author.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusAdmin/Customer/_info.html.twig' with {'customer': product_review.author} %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_form.html.twig deleted file mode 100644 index 3cbf691c4b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_form.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -
-
-
- {{ form_errors(form) }} - {{ form_row(form.title) }} - {{ form_row(form.comment) }} - {{ form_row(form.rating) }} -
-
-
- {% include '@SyliusAdmin/ProductReview/_product.html.twig' %} - {% include '@SyliusAdmin/ProductReview/_author.html.twig' %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_product.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_product.html.twig deleted file mode 100644 index 2e536b548a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductReview/_product.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% set product = product_review.reviewSubject %} - -

- {{ 'sylius.ui.product'|trans }} -

- diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Create/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Create/_breadcrumb.html.twig deleted file mode 100644 index 33997d5bb7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Create/_breadcrumb.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index') }, - { label: resource.product.name|default(resource.product.code), url: path('sylius_admin_product_update', {'id': resource.product.id}) }, - { label: 'sylius.ui.variants'|trans, url: path(configuration.getRouteName('index'), {'productId': resource.product.id}) }, - { label: 'sylius.ui.new'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Create/_headerTitle.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Create/_headerTitle.html.twig deleted file mode 100644 index c12615c805..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Create/_headerTitle.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{{ headers.default(resource.product.name, configuration.vars.icon|default('plus'), configuration.vars.subheader|default(header)|trans) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_breadcrumb.html.twig deleted file mode 100644 index f69da7b55f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_breadcrumb.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index') }, - { label: product.name|default(product.code), url: path('sylius_admin_product_update', {'id': product.id}) }, - { label: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': product.id}) }, - { label: 'sylius.ui.generate'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_content.html.twig deleted file mode 100644 index d3706cb7b7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_content.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} - -{{ form_start(form, {'action': path('sylius_admin_product_variant_generate', {'productId': product.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} -
- {% include '@SyliusAdmin/ProductVariant/Generate/_form.html.twig' %} -
-
- - {% include '@SyliusUi/Form/Buttons/_cancel.html.twig' with {'path': path(configuration.getRouteName('index'), {'productId': product.id})} %} -
-
- {{ sylius_template_event('sylius.admin.product_variant.generate.form', {'resource': resource}) }} -
-{{ form_row(form._token) }} -{{ form_end(form, {'render_rest': false}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_form.html.twig deleted file mode 100644 index e9da5632aa..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_form.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -

{{ 'sylius.ui.variants'|trans }}

-{{ form_row(form.variants) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_header.html.twig deleted file mode 100644 index 5ba128b1e6..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Generate/_header.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{{ headers.default(product.name, 'random', configuration.vars.subheader|default(header)|trans) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Action/updatePositions.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Action/updatePositions.html.twig deleted file mode 100644 index 85812dc1ff..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Action/updatePositions.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -
- -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/inventory.html.twig deleted file mode 100644 index be7507b9e2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/inventory.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -{% if data.isTracked %} -
- - {{ data.onHand }} {{ 'sylius.ui.available_on_hand'|trans }} - {% if data.onHold > 0 %} -
- {{ data.onHold }} {{ 'sylius.ui.reserved'|trans }} -
- {% endif %} -
-{% else %} - - - {{ 'sylius.ui.not_tracked'|trans }} - -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/position.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/position.html.twig deleted file mode 100644 index 9d49c15792..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/position.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -
-
- -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/ProductHeader/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/ProductHeader/_breadcrumb.html.twig deleted file mode 100644 index 2c6b52a90c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/ProductHeader/_breadcrumb.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include configuration.vars.templates.breadcrumb|default('@SyliusAdmin/ProductVariant/Index/_breadcrumb.html.twig') %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/ProductHeader/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/ProductHeader/_content.html.twig deleted file mode 100644 index 37d1aa60a7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/ProductHeader/_content.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{{ headers.default(product.name, configuration.vars.icon|default('cubes'), configuration.vars.subheader|default('sylius.ui.manage_variants')|trans) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_breadcrumb.html.twig deleted file mode 100644 index 2e2879786c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_breadcrumb.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index') }, - { label: product.name|default(product.code), url: path('sylius_admin_product_update', {'id': product.id}) }, - { label: 'sylius.ui.variants'|trans }, - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_header.html.twig deleted file mode 100644 index 87fd67559a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_header.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{{ render(url('sylius_admin_partial_product_show', { - 'id': app.request.attributes.get('productId'), - 'template': '@SyliusAdmin/ProductVariant/Index/_productHeader.html.twig', - 'vars': configuration.vars -})) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_headerWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_headerWidget.html.twig deleted file mode 100644 index 91a4b97019..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_headerWidget.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -
- {% include '@SyliusAdmin/ProductVariant/Index/_header.html.twig' %} - {% include '@SyliusAdmin/Crud/Index/_actions.html.twig' %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_productHeader.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_productHeader.html.twig deleted file mode 100644 index 4ab37d09f7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Index/_productHeader.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -
- {{ sylius_template_event('sylius.admin.product_variant.index.header.content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_channelPricings.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_channelPricings.html.twig deleted file mode 100644 index 5b4aa7bd43..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_channelPricings.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -
-

{{ 'sylius.ui.channel_pricings'|trans }}

-
- {{ 'sylius.ui.price_details'|trans }} -
- {{ 'sylius.ui.original_price_details'|trans }} -
- {{ 'sylius.ui.minimum_price_details'|trans }} -
-
- {{ form_errors(form.channelPricings) }} - {% for channelCode, channelPricing in form.channelPricings %} -
-
- {{ channelPricing.vars.label }} -
- {% if channelCode not in product_variant.product.channels|map(channel => channel.code) %} -
- {{ 'sylius.ui.product.product_not_active_in_channel'|trans }} -
- {% endif %} - {{ form_row(channelPricing.price) }} - {{ form_row(channelPricing.originalPrice) }} - {{ form_row(channelPricing.minimumPrice) }} -
- {% endfor %} -
- - {{ sylius_template_event(['sylius.admin.product_variant.' ~ action ~ '.tab_channel_pricings', 'sylius.admin.product_variant.channelPricings'], {'form': form}) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_details.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_details.html.twig deleted file mode 100644 index c019c97757..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_details.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} - -
-

{{ 'sylius.ui.details'|trans }}

- -
- {{ translationForm(form.translations) }} - -
- {{ form_row(form.code) }} - {{ form_row(form.enabled) }} -
- -
-
- {{ form_row(form.shippingCategory) }} -
-
- {{ form_row(form.shippingRequired) }} -
-
- {% if form.optionValues is defined and form.optionValues|length > 0 %} - -
-

{{ 'sylius.ui.options'|trans }}

- {% for option_form in form.optionValues %} - {{ form_row(option_form) }} - {% endfor %} -
- {% endif %} - -
-

{{ 'sylius.ui.properties'|trans }}

- {{ form_row(form.height) }} - {{ form_row(form.width) }} - {{ form_row(form.depth) }} - {{ form_row(form.weight) }} -
-
- - {{ sylius_template_event(['sylius.admin.product_variant.' ~ action ~ '.tab_details', 'sylius.admin.product_variant.tab_details'], {'form': form}) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_inventory.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_inventory.html.twig deleted file mode 100644 index e1784fee8b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_inventory.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -
- {{ sylius_template_event('sylius.admin.product_variant.tab_inventory_content', _context) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_inventoryContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_inventoryContent.html.twig deleted file mode 100644 index 65576cfc3c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_inventoryContent.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -

{{ 'sylius.ui.inventory'|trans }}

-
- {{ form_row(form.onHand) }} - {{ form_row(form.tracked) }} - -
- {{ form_help(form.tracked) }} -
- - {{ form_row(form.version) }} -
- -{{ sylius_template_event(['sylius.admin.product_variant.' ~ action ~ '.tab_inventory', 'sylius.admin.product_variant.tab_inventory'], {'form': form}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_taxes.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_taxes.html.twig deleted file mode 100644 index 7517bdaa21..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Tab/_taxes.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -
-

{{ 'sylius.ui.taxes'|trans }}

- {{ form_row(form.taxCategory) }} - - {{ sylius_template_event(['sylius.admin.product_variant.' ~ action ~ '.tab_taxes', 'sylius.admin.product_variant.tab_taxes'], {'form': form}) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Update/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Update/_breadcrumb.html.twig deleted file mode 100644 index 8b772535bb..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Update/_breadcrumb.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index') }, - { label: resource.product.name, url: path('sylius_admin_product_update', {'id': resource.product.id}) }, - { label: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': resource.product.id}) }, - { label: resource.name|default(resource.code) }, - { label: 'sylius.ui.edit'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Update/_toolbar.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Update/_toolbar.html.twig deleted file mode 100644 index 70e4776e15..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Update/_toolbar.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -
-
- {% include '@SyliusAdmin/Product/_showInShopButton.html.twig' with {'product': product_variant.product} %} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/_form.html.twig deleted file mode 100644 index 6dc8c9bd0a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/_form.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{% set menu = knp_menu_get('sylius.admin.product_variant_form', [], {'product_variant': product_variant}) %} -{{ knp_menu_render(menu, {'template': '@SyliusAdmin/ProductVariant/_menu.html.twig', 'form': form, 'product_variant': product_variant}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/_menu.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/_menu.html.twig deleted file mode 100644 index 651c3163c9..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/_menu.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% extends 'knp_menu.html.twig' %} - -{% if 'create' in app.request.attributes.get('_route') %} - {% set action = 'create' %} -{% else %} - {% set action = 'update' %} -{% endif %} - -{% block list %} -{% set form = (options.form) %} -
-
- -
-
- {{ form_errors(form) }} -
- {% for item in item.children %} - {% include item.attribute('template') with {'form': form, 'product_variant': options.product_variant} %} - {% endfor %} -
-
-
-{% endblock %} - -{% block item %} - {%- set attributes = item.attributes %} - {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %} - {%- if item.actsLikeFirst %} - {%- set classes = classes|merge(['active']) %} - {%- endif %} - {%- if classes is not empty %} - {%- set attributes = attributes|merge({'class': classes|join(' ')}) %} - {%- endif %} - {{ item.label|trans }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/generate.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/generate.html.twig deleted file mode 100644 index fd56d23021..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/generate.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% set header = 'sylius.ui.generate_variants' %} - -{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.product_variant.generate.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/index.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/index.html.twig deleted file mode 100644 index a463a3afdf..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/index.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{% set definition = resources.definition %} -{% set data = resources.data %} - -{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} - -{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.product_variant.index.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/codeExclusiveAndCouponBased.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/codeExclusiveAndCouponBased.html.twig deleted file mode 100644 index ec2a9c1ff7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/codeExclusiveAndCouponBased.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if data.exclusive %} -
{{ 'sylius.ui.exclusive'|trans }}
-
-{% endif %} -{% if data.couponBased %} -
{{ 'sylius.ui.coupon_based'|trans }}
-
-{% endif %} -{{ data.code }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/usage.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/usage.html.twig deleted file mode 100644 index 959712c5e2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/usage.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -{% if data.usageLimit is empty %} - - {{ data.used }} - - / - -{% else %} - {% set color = 'teal' %} - - {% if data.used == data.usageLimit %} - {% set color = 'red' %} - {% elseif data.used > data.usageLimit/2 %} - {% set color = 'yellow' %} - {% endif %} - - {{ data.used }} - - / - - {{ data.usageLimit }} - -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/usedWithUsageLimit.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/usedWithUsageLimit.html.twig deleted file mode 100644 index 0b405d25c7..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Grid/Field/usedWithUsageLimit.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -
- {{ data.used }} - {% if data.usageLimit %} - /{{ data.usageLimit }} - {% endif %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Show/_translations.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Show/_translations.html.twig deleted file mode 100644 index 1d807ef960..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/Show/_translations.html.twig +++ /dev/null @@ -1,21 +0,0 @@ - - -
- {% for translation in promotion.translations %} -
- - - {{ translation.locale|sylius_locale_name }} -
-
- - - - - - - -
{{ 'sylius.ui.label'|trans }}{{ translation.label }}
-
- {% endfor %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/_form.html.twig deleted file mode 100644 index 6180553ad0..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/_form.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} - -
-
- {{ form_errors(form) }} -
-
- {{ form_row(form.code) }} - {{ form_row(form.name) }} -
- {{ form_row(form.description) }} -
-
-
-
-
- {{ form_row(form.usageLimit) }} - {{ form_row(form.couponBased) }} - {{ form_row(form.exclusive) }} -
- {{ form_widget(form.appliesToDiscounted) }} - {{ form_label(form.appliesToDiscounted) }} - {{ 'sylius.form.promotion.applies_to_discounted_details'|trans }} -
-
-
- {{ form_row(form.priority) }} - {{ form_row(form.channels) }} -
-
-

{{ 'sylius.ui.start_date'|trans }} & {{ 'sylius.ui.end_date'|trans }}

- -
- {{ form_row(form.startsAt) }} - {{ form_row(form.endsAt) }} -
-
-
-
- {{ translationForm(form.translations) }} -
-
-

{{ 'sylius.ui.configuration'|trans }}

- -
-
- {{ form_row(form.rules) }} -
-
- {{ form_row(form.actions) }} -
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/_toolbar.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/_toolbar.html.twig deleted file mode 100644 index 831b8e68e9..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Promotion/_toolbar.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% set menu = knp_menu_get('sylius.admin.promotion.update', [], {'promotion': promotion}) %} - -{% if promotion.couponBased == true %} -
- {{ knp_menu_render(menu, {'template': '@SyliusUi/Menu/top.html.twig'}) }} -
-{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Create/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Create/_breadcrumb.html.twig deleted file mode 100644 index 6c7a35bd5a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Create/_breadcrumb.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.promotions'|trans, url: path('sylius_admin_promotion_index') }, - { label: resource.promotion.name|default(resource.promotion.code), url: path('sylius_admin_promotion_update', {'id': resource.promotion.id}) }, - { label: 'sylius.ui.coupons'|trans, url: path(configuration.getRouteName('index'), {'promotionId': resource.promotion.id}) }, - { label: 'sylius.ui.new'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Create/_headerTitle.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Create/_headerTitle.html.twig deleted file mode 100644 index d2bcc5306b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Create/_headerTitle.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{{ headers.default(resource.promotion.name, configuration.vars.icon|default('plus'), configuration.vars.subheader|default(header)|trans) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_breadcrumb.html.twig deleted file mode 100644 index b2b27e8059..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_breadcrumb.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.promotions'|trans, url: path('sylius_admin_promotion_index') }, - { label: promotion.name|default(promotion.code), url: path('sylius_admin_promotion_update', {'id': promotion.id}) }, - { label: 'sylius.ui.coupons'|trans, url: path('sylius_admin_promotion_coupon_index', {'promotionId': promotion.id}) }, - { label: 'sylius.ui.generate'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_form.html.twig deleted file mode 100644 index e48a4ad2f2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_form.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -
-
-
-
- {{ form_row(form.prefix) }} - {{ form_row(form.codeLength) }} - {{ form_row(form.suffix) }} -
-
-
-
-
-
-
- {{ form_errors(form) }} - {{ form_row(form.amount) }} -
-
-
-
-

{{ 'sylius.ui.expiration_and_usage_limits'|trans }}

-
- {{ form_row(form.expiresAt) }} - {{ form_row(form.usageLimit) }} -
-
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_formWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_formWidget.html.twig deleted file mode 100644 index 1dce7deb8a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_formWidget.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} - -{{ form_start(form, {'action': path('sylius_admin_promotion_coupon_generate', {'promotionId': promotion.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} -
- {% include '@SyliusAdmin/PromotionCoupon/Generate/_form.html.twig' %} -
-
- - {% include '@SyliusUi/Form/Buttons/_cancel.html.twig' with {'path': path(configuration.getRouteName('index'), {'promotionId': promotion.id})} %} -
-
- - {{ sylius_template_event('sylius.admin.promotion_coupon.generate.form', {'resource': promotion}) }} -
-{{ form_row(form._token) }} -{{ form_end(form, {'render_rest': false}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_header.html.twig deleted file mode 100644 index 587482c2cf..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Generate/_header.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{{ headers.default(promotion.name, 'random', configuration.vars.subheader|default(header)|trans) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_breadcrumb.html.twig deleted file mode 100644 index 40b51d40fa..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_breadcrumb.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.promotions'|trans, url: path('sylius_admin_promotion_index') }, - { label: promotion.name|default(promotion.code), url: path('sylius_admin_promotion_update', {'id': promotion.id}) }, - { label: 'sylius.ui.coupons'|trans }, - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_header.html.twig deleted file mode 100644 index c2348b12bd..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_header.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{{ render(url('sylius_admin_partial_promotion_show', { - 'id': app.request.attributes.get('promotionId'), - 'template': '@SyliusAdmin/PromotionCoupon/Index/_promotionHeader.html.twig', - 'vars': configuration.vars -})) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_headerWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_headerWidget.html.twig deleted file mode 100644 index eab086661d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_headerWidget.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -
- {% include '@SyliusAdmin/PromotionCoupon/Index/_header.html.twig' %} - {% include '@SyliusAdmin/Crud/Index/_actions.html.twig' %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_promotionHeader.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_promotionHeader.html.twig deleted file mode 100644 index 08b5209ebc..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Index/_promotionHeader.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -
- {{ headers.default(promotion.name, configuration.vars.icon|default('tags'), configuration.vars.subheader|default('sylius.ui.manage_coupons')|trans) }} - - {% include configuration.vars.templates.breadcrumb|default('@SyliusAdmin/PromotionCoupon/Index/_breadcrumb.html.twig') %} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Update/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Update/_breadcrumb.html.twig deleted file mode 100644 index 8fd6c4412f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/Update/_breadcrumb.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.promotions'|trans, url: path('sylius_admin_promotion_index') }, - { label: resource.promotion.name, url: path('sylius_admin_promotion_update', {'id': resource.promotion.id}) }, - { label: 'sylius.ui.promotion_coupons'|trans, url: path('sylius_admin_promotion_coupon_index', {'promotionId': resource.promotion.id}) }, - { label: resource.code|default(resource.id) }, - { label: 'sylius.ui.edit'|trans } - ] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/_form.html.twig deleted file mode 100644 index f03a0b2e86..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/_form.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -
- {{ form_errors(form) }} - {{ form_row(form.code) }} -
-
-

{{ 'sylius.ui.expiration_and_usage_limits'|trans }}

-
- {{ form_row(form.usageLimit) }} - {{ form_row(form.perCustomerUsageLimit) }} -
-
- {{ form_row(form.reusableFromCancelledOrders) }} - {{ form_row(form.expiresAt) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/generate.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/generate.html.twig deleted file mode 100644 index 3cc8bff6b6..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/generate.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% set header = 'sylius.ui.generate_coupons' %} - -{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.promotion_coupon.generate.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/index.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/index.html.twig deleted file mode 100644 index c23ddf84c5..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/PromotionCoupon/index.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% import '@SyliusUi/Macro/headers.html.twig' as headers %} - -{% set definition = resources.definition %} -{% set data = resources.data %} - -{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} - -{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.promotion_coupon.index.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/Form/_requestPasswordResetButton.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/Form/_requestPasswordResetButton.html.twig deleted file mode 100644 index f12d85838a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/Form/_requestPasswordResetButton.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ 'sylius.ui.forgot_password'|trans }} - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_email.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_email.html.twig deleted file mode 100644 index 66ddd9e922..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_email.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ form_row(form.email, sylius_test_form_attribute('email')) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_form.html.twig deleted file mode 100644 index ac24b870fe..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_form.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -{% form_theme form '@SyliusUi/Form/theme.html.twig' %} - -
-
- {{ sylius_template_event('sylius.admin.request_password_reset.before_form') }} - - {{ form_start(form, {action: path('sylius_admin_request_password_reset'), 'attr': {'class': 'ui large loadable form', 'novalidate': 'novalidate'}}) }} - -
- {{ sylius_template_event('sylius.admin.request_password_reset.form.content', _context) }} -
- {{ form_row(form._token) }} - {{ form_end(form, {'render_rest': false}) }} - - {{ sylius_template_event('sylius.admin.request_password_reset.after_form') }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_submit.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_submit.html.twig deleted file mode 100644 index da6446a138..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/RequestPasswordReset/_submit.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/Form/_passwords.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/Form/_passwords.html.twig deleted file mode 100644 index ab883cac32..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/Form/_passwords.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{{ form_row(form.password.newPassword, sylius_test_form_attribute('new-password')) }} -{{ form_row(form.password.confirmNewPassword, sylius_test_form_attribute('confirm-new-password')) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/Form/_submit.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/Form/_submit.html.twig deleted file mode 100644 index ad540447bb..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/Form/_submit.html.twig +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/_content.html.twig deleted file mode 100644 index c29e7b8157..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/_content.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -
-
- {{ sylius_template_event('sylius.admin.reset_password.form', _context) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/_form.html.twig deleted file mode 100644 index d56c235c5c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/ResetPassword/_form.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} - -{{ form_start(form, {action: path('sylius_admin_password_reset', {'token': app.request.attributes.get('token')}), 'attr': {'class': 'ui large loadable form', 'novalidate': 'novalidate'}}) }} -
- {{ sylius_template_event('sylius.admin.reset_password.form.content', _context) }} -
- {{ form_row(form._token) }} -{{ form_end(form, {'render_rest': false}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/_content.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/_content.html.twig deleted file mode 100644 index 3cdf42fac3..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/_content.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -{% include '@SyliusUi/Security/_login.html.twig' - with { - 'action': path('sylius_admin_login_check'), - 'paths': {'logo': asset('build/admin/images/logo.png', 'admin')} - } -%} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/_logo.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/_logo.html.twig deleted file mode 100644 index 06765f40a9..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/_logo.html.twig +++ /dev/null @@ -1 +0,0 @@ -{% include '@SyliusUi/Security/_logo.html.twig' with {'paths': {'logo': asset('build/admin/images/logo.png', 'admin')}} %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/login.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Security/login.html.twig deleted file mode 100644 index 622287c2a8..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/login.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -{% extends '@SyliusUi/Layout/centered.html.twig' %} - -{% block title %}Sylius | {{ 'sylius.ui.administration_panel_login'|trans }}{% endblock %} - -{% block stylesheets %} - {{ sylius_template_event('sylius.admin.layout.stylesheets') }} -{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.login.content', _context) }} -{% endblock %} - -{% block javascripts %} - {{ sylius_template_event('sylius.admin.layout.javascripts') }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/Action/_shipWithTrackingCodeContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/Action/_shipWithTrackingCodeContent.html.twig deleted file mode 100644 index 69b8d7551c..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/Action/_shipWithTrackingCodeContent.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{% if sylius_sm_can(data, 'sylius_shipment', 'ship') %} - {{ render(controller('sylius.controller.shipment::updateAction', { - '_sylius': { - 'event': 'ship', - 'repository': { - 'method': 'findOneByOrderId', - 'arguments': { - 'id': data.id, - 'orderId': data.order.id - } - }, - 'state_machine': { - 'graph': 'sylius_shipment', - 'transition': 'ship' - }, - 'section': 'admin', - 'permission': true, - 'template': '@SyliusAdmin/Shipment/Grid/_ship.html.twig', - 'form': 'Sylius\\Bundle\\ShippingBundle\\Form\\Type\\ShipmentShipType', - 'vars': { - 'route': { - 'parameters': { - 'id': data.id, - 'orderId': data.order.id - } - } - } - } - })) }} -{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/Action/shipWithTrackingCode.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/Action/shipWithTrackingCode.html.twig deleted file mode 100644 index c3a7cc8a94..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/Action/shipWithTrackingCode.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ sylius_template_event('sylius.admin.shipment.ship_with_tracking_code', _context) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/_ship.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/_ship.html.twig deleted file mode 100644 index a16d3ffa40..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/_ship.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ sylius_template_event('sylius.admin.shipment.grid.ship', _context) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/_shipContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/_shipContent.html.twig deleted file mode 100644 index 616a01cb85..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Grid/_shipContent.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{{ form_start(form, {'action': path('sylius_admin_shipment_ship', configuration.vars.route.parameters), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} - -
- {{ form_widget(form.tracking, {'attr': {'placeholder': 'sylius.ui.tracking_code'|trans ~ '...'}}) }} - -
-{{ form_row(form._token) }} -{{ form_end(form, {'render_rest': false}) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Partial/_ship.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Partial/_ship.html.twig deleted file mode 100644 index e5649a2ebd..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Partial/_ship.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ sylius_template_event('sylius.admin.shipment.partial.ship', _context) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Partial/_shipContent.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Partial/_shipContent.html.twig deleted file mode 100644 index a1fcd93bf2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Partial/_shipContent.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -
- {{ form_start(form, {'action': path('sylius_admin_order_shipment_ship', configuration.vars.route.parameters), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} - -
- {{ form_widget(form.tracking, {'attr': {'placeholder': 'sylius.ui.tracking_code'|trans ~ '...'}}) }} - -
- {{ form_row(form._token) }} - {{ form_end(form, {'render_rest': false}) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_breadcrumb.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_breadcrumb.html.twig deleted file mode 100644 index a1dbd0689b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_breadcrumb.html.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} - -{% set breadcrumbs = [ - { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, - { label: 'sylius.ui.orders'|trans, url: path('sylius_admin_order_index') }, - { label: '#' ~ shipment.order.number, url: path('sylius_admin_order_show', {'id': shipment.order.id}) }, - { label: 'sylius.ui.shipments'|trans}, - { label: shipment.id } -] -%} - -{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_header.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_header.html.twig deleted file mode 100644 index f4c965b2b2..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_header.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -

- -
- {{ 'sylius.ui.shipment_for_order'|trans }} #{{ shipment.order.number }} -
-
-
- {% include '@SyliusAdmin/Common/Label/shipmentState.html.twig' with {'data': shipment.state} %} -
-
-
-
-

diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_headerWidget.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_headerWidget.html.twig deleted file mode 100644 index 80093d6e77..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_headerWidget.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} - -
-
- {% include '@SyliusAdmin/Shipment/Show/_header.html.twig' %} -
-
- {{ buttons.default(app.request.headers.get('referer'), '', 'back', 'arrow alternate circle left outline') }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_shipmentUnits.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_shipmentUnits.html.twig deleted file mode 100644 index 4661b26304..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/Show/_shipmentUnits.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -
- - - - - - - - - {% for unit in shipment.units %} - - - - - {% endfor %} - -
{{ 'sylius.ui.product'|trans }}{{ 'sylius.ui.variant'|trans }}
{{ unit.orderItem.product.name }}{{ unit.orderItem.variant.name }}
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/show.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/show.html.twig deleted file mode 100644 index d92581bbe4..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Shipment/show.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends '@SyliusAdmin/layout.html.twig' %} - -{% block title %}{{ 'sylius.ui.shipment'|trans }} | {{ shipment.id }}{% endblock %} - -{% block content %} - {{ sylius_template_event('sylius.admin.shipment.show.content', _context) }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingCategory/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingCategory/_form.html.twig deleted file mode 100644 index bc6e1245bf..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingCategory/_form.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -
-
-
- {{ form_errors(form) }} -
- {{ form_row(form.code) }} - {{ form_row(form.name) }} -
-
-
-
-
- {{ form_row(form.description) }} -
-
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingMethod/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingMethod/_form.html.twig deleted file mode 100644 index 7b353d14c4..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingMethod/_form.html.twig +++ /dev/null @@ -1,44 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationForm %} - -
-
-
- {{ form_errors(form) }} -
- {{ form_row(form.code) }} - {{ form_row(form.zone) }} - {{ form_row(form.position) }} -
- {{ form_row(form.enabled) }} -

{{ 'sylius.ui.availability'|trans }}

- {{ form_row(form.channels) }} -

{{ 'sylius.ui.category_requirements'|trans }}

- {{ form_row(form.category) }} - {% for categoryRequirementChoiceForm in form.categoryRequirement %} - {{ form_row(categoryRequirementChoiceForm) }} - {% endfor %} -

{{ 'sylius.ui.taxes'|trans }}

- {{ form_row(form.taxCategory) }} -

{{ 'sylius.ui.shipping_charges'|trans }}

- {{ form_row(form.calculator) }} - {% for name, calculatorConfigurationPrototype in form.vars.prototypes %} -
-
- {% endfor %} -
- {% if form.configuration is defined %} - {{ form_widget(form.configuration) }} - {% endif %} -
- -

{{ 'sylius.ui.rules'|trans }}

-
- {% include '@SyliusAdmin/ShippingMethod/_rules.html.twig' %} -
-
-
-
- {{ translationForm(form.translations) }} -
-
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingMethod/_rules.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingMethod/_rules.html.twig deleted file mode 100644 index 5f16afcd33..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ShippingMethod/_rules.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -
- -
- {{ 'sylius.form.shipping_method.rules_help'|trans }} -
-
-{{ form_row(form.rules) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/TaxCategory/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/TaxCategory/_form.html.twig deleted file mode 100644 index c12ca90e1a..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/TaxCategory/_form.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -{{ form_errors(form) }} -
- {{ form_row(form.code) }} - {{ form_row(form.name) }} -
-{{ form_row(form.description) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/TaxRate/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/TaxRate/_form.html.twig deleted file mode 100644 index 8acce72ae8..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/TaxRate/_form.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{{ form_errors(form) }} - -
-

{{ 'sylius.ui.general_info'|trans }}

-
- {{ form_row(form.code) }} - {{ form_row(form.name) }} -
-
- -
-

{{ 'sylius.ui.criteria'|trans }}

-
- {{ form_row(form.category) }} - {{ form_row(form.zone) }} -
-
- -
-

{{ 'sylius.ui.date_range'|trans }}

-
- {{ form_row(form.startDate) }} - {{ form_row(form.endDate) }} -
-
- -
-

{{ 'sylius.ui.taxes'|trans }}

- {{ form_row(form.calculator) }} - {{ form_row(form.amount) }} - {{ form_row(form.includedInPrice) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_form.html.twig deleted file mode 100644 index 1156402a4d..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_form.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationFormWithSlug %} - -
- {{ form_errors(form) }} -
- {{ form_row(form.code) }} - {{ form_row(form.parent) }} -
-
- {{ form_row(form.enabled) }} -
-
-{{ translationFormWithSlug(form.translations, '@SyliusAdmin/Taxon/_slugField.html.twig', taxon) }} - -{% include '@SyliusAdmin/Taxon/_media.html.twig' %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_media.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_media.html.twig deleted file mode 100644 index 68633b4e40..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_media.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% form_theme form '@SyliusUi/Form/imagesTheme.html.twig' %} - -
-

{{ 'sylius.ui.media'|trans }}

-
- {{ form_row(form.images, {'label': false}) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_slugField.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_slugField.html.twig deleted file mode 100644 index b541cea194..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_slugField.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -
- {{ form_label(slugField) }} - {% if resource.slug == null %} - {{ form_widget(slugField, {'attr': {'data-url': path('sylius_admin_ajax_generate_taxon_slug'), 'data-parent': app.request.attributes.get('id')}}) }} - {% else %} -
- {{ form_widget(slugField, {'attr': {'readonly': 'readonly', 'data-url': path('sylius_admin_ajax_generate_taxon_slug'), 'data-parent': resource.parent ? resource.parent.id : null}}) }} - - - -
- {% endif %} - {{ form_errors(slugField) }} -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_taxonTree.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_taxonTree.html.twig deleted file mode 100644 index f1d26519c3..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_taxonTree.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ render(path('sylius_admin_partial_taxon_tree', {'template': '@SyliusAdmin/Taxon/_treeWithButtons.html.twig'})) }} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_treeWithButtons.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_treeWithButtons.html.twig deleted file mode 100644 index fe5492abe3..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_treeWithButtons.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} -{% import _self as tree %} - -{% macro render(taxons) %} - {% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} - {% import _self as tree %} - - -{% endmacro %} - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_treeWithoutButtons.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_treeWithoutButtons.html.twig deleted file mode 100644 index 0d24c70fbd..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/_treeWithoutButtons.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{% import _self as tree %} - -{% macro render(taxons) %} - {% import _self as tree %} - -
    - {% for taxon in taxons %} -
  • - - {{ tree.render(taxon.children) }} -
  • - {% endfor %} -
-{% endmacro %} - - - - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/create.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/create.html.twig deleted file mode 100644 index 95813c7b39..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/create.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{% extends '@SyliusAdmin/Crud/create.html.twig' %} - -{% block content %} - {{ sylius_template_event('sylius.admin.taxon.create.before_content', {'resource': resource}) }} - -
-
- {{ sylius_template_event('sylius.admin.taxon.create.taxon_tree', {'resource': resource}) }} -
-
- {{ parent() }} -
-
-{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/update.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/update.html.twig deleted file mode 100644 index b41c9c751b..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Taxon/update.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{% extends '@SyliusAdmin/Crud/update.html.twig' %} - -{% block content %} - {{ sylius_template_event('sylius.admin.taxon.update.before_content', {'resource': resource}) }} - -
-
- {{ sylius_template_event('sylius.admin.taxon.update.taxon_tree', {'resource': resource}) }} -
-
- {{ parent() }} -
-
-{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Zone/_form.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/Zone/_form.html.twig deleted file mode 100644 index fa0d02873f..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Zone/_form.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -{{ form_errors(form) }} -
-
- {{ form_row(form.type) }} - {{ form_row(form.code) }} -
-
- {{ form_row(form.name) }} - {{ form_row(form.scope) }} -
-
-
-

{{ 'sylius.ui.members'|trans }}

- {{ form_row(form.members, {'label': false}) }} -
- - diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/_divider.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/_divider.html.twig deleted file mode 100644 index 54b2e75339..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/_divider.html.twig +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/layout.html.twig b/src/Sylius/Bundle/AdminBundle/Resources/views/layout.html.twig deleted file mode 100644 index dc40065bb1..0000000000 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/layout.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{% extends '@SyliusAdmin/Layout/layout.html.twig' %} - -{% block title %} | Sylius{% endblock %} - -{% block stylesheets %} - {{ sylius_template_event('sylius.admin.layout.stylesheets') }} -{% endblock %} - -{% block flash_messages %} - {% include '@SyliusAdmin/Layout/_flashes.html.twig' %} -{% endblock %} - -{% block topbar %} - {{ sylius_template_event('sylius.admin.layout.topbar_left') }} - -
- - {{ sylius_template_event('sylius.admin.layout.topbar_middle') }} - -
- - {{ sylius_template_event('sylius.admin.layout.topbar_right') }} -{% endblock %} - -{% block sidebar %} - {{ sylius_template_event('sylius.admin.layout.sidebar') }} -{% endblock %} - -{% block footer %} -{{ 'sylius.ui.powered_by'|trans }} Sylius v{{ sylius_meta.version }}. {{ 'sylius.ui.see_issue'|trans }}? {{ 'sylius.ui.report_it'|trans }}! -{% endblock %} - -{% block javascripts %} - {{ sylius_template_event('sylius.admin.layout.javascripts') }} -{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/AttributeExtension.php b/src/Sylius/Bundle/AdminBundle/Twig/AttributeExtension.php new file mode 100644 index 0000000000..569208d8f2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/AttributeExtension.php @@ -0,0 +1,33 @@ +attributeTypeRegistry, 'all']), + ]; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/CatalogPromotion/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/CatalogPromotion/FormComponent.php new file mode 100644 index 0000000000..d730402ba4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/CatalogPromotion/FormComponent.php @@ -0,0 +1,73 @@ +fieldNameToPropertyPath($name, $this->formName); + $data = $propertyAccessor->getValue($this->formValues, $propertyPath); + + if (!\is_array($data)) { + $propertyAccessor->setValue($this->formValues, $propertyPath, []); + $data = []; + } + + $propertyAccessor->setValue( + $this->formValues, + sprintf('%s[%s]', $propertyPath, $this->resolveItemIndex($data)), + ['type' => $type], + ); + } + + protected function instantiateForm(): FormInterface + { + return $this->formFactory->create($this->formClass, $this->resource); + } + + /** @param array> $data */ + private function resolveItemIndex(array $data): int + { + return [] !== $data ? max(array_keys($data)) + 1 : 0; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Channel/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Channel/FormComponent.php new file mode 100644 index 0000000000..d10bd0a80c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Channel/FormComponent.php @@ -0,0 +1,46 @@ +formFactory->create($this->formClass, $this->channel); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Country/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Country/FormComponent.php new file mode 100644 index 0000000000..1c522600cd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Country/FormComponent.php @@ -0,0 +1,46 @@ +formFactory->create($this->formClass, $this->country); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Customer/OrderStatisticsComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Customer/OrderStatisticsComponent.php new file mode 100644 index 0000000000..d76acd6ff1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Customer/OrderStatisticsComponent.php @@ -0,0 +1,57 @@ + $customerRepository + */ + public function __construct( + private readonly CustomerRepositoryInterface $customerRepository, + private readonly CustomerStatisticsProviderInterface $statisticsProvider, + ) { + } + + /** + * @return PerChannelCustomerStatistics[] + */ + #[ExposeInTemplate] + public function getStatistics(): array + { + $customer = $this->customerRepository->find($this->customerId); + if (null === $customer) { + return []; + } + + return $this->statisticsProvider->getCustomerStatistics($customer)->getPerChannelsStatistics(); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/NewCustomersComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/NewCustomersComponent.php new file mode 100644 index 0000000000..60d71399ba --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/NewCustomersComponent.php @@ -0,0 +1,42 @@ + $customerRepository + */ + public function __construct( + private readonly CustomerRepositoryInterface $customerRepository, + ) { + } + + /** + * @return array + */ + #[ExposeInTemplate] + public function getNewCustomers(): array + { + return $this->customerRepository->findLatest($this->limit); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/NewOrdersComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/NewOrdersComponent.php new file mode 100644 index 0000000000..66fd7de260 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/NewOrdersComponent.php @@ -0,0 +1,42 @@ + $orderRepository + */ + public function __construct( + private readonly OrderRepositoryInterface $orderRepository, + ) { + } + + /** + * @return array + */ + #[ExposeInTemplate] + public function getNewOrders(): array + { + return $this->orderRepository->findLatest($this->limit); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/StatisticsComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/StatisticsComponent.php new file mode 100644 index 0000000000..a38ec3f44c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Dashboard/StatisticsComponent.php @@ -0,0 +1,90 @@ + $channelRepository + */ + public function __construct( + private readonly ChannelRepositoryInterface $channelRepository, + private readonly StatisticsDataProviderInterface $statisticsDataProvider, + ) { + } + + /** + * @return array + * + * @throws \Exception + */ + #[ExposeInTemplate] + public function getStatistics(): array + { + /** @var ChannelInterface $channel */ + $channel = $this->channelRepository->findOneByCode($this->channelCode); + + return $this->statisticsDataProvider->getRawData( + $channel, + new \DateTime($this->startDate), + new \DateTime($this->endDate), + $this->range, + ); + } + + #[LiveAction] + public function changeRange( + #[LiveArg] string $name, + #[LiveArg] string $range, + #[LiveArg] string $startDate, + #[LiveArg] string $endDate, + ): void { + $this->rangeName = $name; + $this->range = $range; + $this->startDate = date('Y-m-d', strtotime($startDate)); + $this->endDate = date('Y-m-d', strtotime($endDate)); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Order/AddressHistoryComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Order/AddressHistoryComponent.php new file mode 100644 index 0000000000..32a9822e69 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Order/AddressHistoryComponent.php @@ -0,0 +1,43 @@ + $addressLogRepository */ + public function __construct( + private readonly RepositoryInterface $addressLogRepository, + ) { + } + + /** @return AddressLogEntry[] */ + #[ExposeInTemplate] + public function getAddressLogs(): array + { + return $this->addressLogRepository->findBy( + ['objectId' => $this->addressId], + ['loggedAt' => $this->sort], + ); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Order/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Order/FormComponent.php new file mode 100644 index 0000000000..4710081033 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Order/FormComponent.php @@ -0,0 +1,46 @@ +formFactory->create($this->formClass, $this->order, ['add_build_address_form_subscriber' => false]); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/PaymentMethod/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/PaymentMethod/FormComponent.php new file mode 100644 index 0000000000..d2094949bb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/PaymentMethod/FormComponent.php @@ -0,0 +1,46 @@ +formFactory->create($this->formClass, $this->paymentMethod); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/FormComponent.php new file mode 100644 index 0000000000..3367c8a354 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/FormComponent.php @@ -0,0 +1,191 @@ + */ + #[LiveProp(writable: true, hydrateWith: 'hydrateAttributesToBeAdded', dehydrateWith: 'dehydrateAttributesToBeAdded')] + public array $attributesToBeAdded = []; + + #[LiveProp(writable: false)] + public bool $isSimple = false; + + /** + * @param class-string $formClass + * @param RepositoryInterface $productAttributeRepository + */ + public function __construct( + private readonly FormFactoryInterface $formFactory, + private readonly string $formClass, + private readonly SlugGeneratorInterface $slugGenerator, + private readonly RepositoryInterface $productAttributeRepository, + private readonly ProductFactoryInterface $productFactory, + ) { + } + + protected function instantiateForm(): FormInterface + { + if (null === $this->resource) { + /** @var Product $product */ + $product = $this->isSimple ? $this->productFactory->createWithVariant() : $this->productFactory->createNew(); + $this->resource = $product; + } + + return $this->formFactory->create($this->formClass, $this->resource); + } + + /** + * @return array> + */ + #[ExposeInTemplate] + public function getMappedProductAttributes(): array + { + $mappedAttributes = []; + + $attributes = $this->getForm()->createView()->children['attributes']; + + foreach ($attributes->children as $attribute) { + /** @var ProductAttributeValueInterface $productAttributeValue */ + $productAttributeValue = $attribute->vars['value']; + + $mappedAttributes[$productAttributeValue->getAttribute()->getCode()][$productAttributeValue->getLocaleCode()] = $attribute; + } + + return $mappedAttributes; + } + + #[LiveAction] + public function applyToAll(#[LiveArg] string $attributeCode, #[LiveArg] string $localeCode): void + { + $matchingAttributes = array_filter( + $this->formValues['attributes'], + fn (array $value) => $value['attribute'] === $attributeCode && $value['localeCode'] === $localeCode, + ); + $currentValue = array_pop($matchingAttributes)['value']; + + $this->formValues['attributes'] = array_map( + fn (array $value) => $value['attribute'] === $attributeCode + ? ['attribute' => $attributeCode, 'localeCode' => $value['localeCode'], 'value' => $currentValue] + : $value, + $this->formValues['attributes'], + ); + } + + #[LiveAction] + public function removeAttribute(#[LiveArg] string $attributeCode): void + { + $this->formValues['attributes'] = array_filter( + $this->formValues['attributes'], + fn (array $value) => $value['attribute'] !== $attributeCode, + ); + $this->dispatchBrowserEvent(self::ATTRIBUTE_REMOVED_EVENT, ['attributeCode' => $attributeCode]); + } + + #[LiveAction] + public function addAttributes(): void + { + foreach ($this->attributesToBeAdded as $attributeCode) { + $productAttribute = $this->productAttributeRepository->findOneBy(['code' => $attributeCode]); + + if (!$productAttribute->isTranslatable()) { + $this->formValues['attributes'][] = [ + 'attribute' => $attributeCode, + 'localeCode' => null, + 'value' => '', + ]; + + continue; + } + + foreach ($this->formValues['translations'] as $localesCode => $translation) { + $this->formValues['attributes'][] = [ + 'attribute' => $attributeCode, + 'localeCode' => $localesCode, + 'value' => '', + ]; + } + } + + $this->dispatchBrowserEvent(self::AUTOCOMPLETE_CLEAR_REQUESTED_EVENT); + } + + #[LiveAction] + public function generateProductSlug(#[LiveArg] string $localeCode): void + { + $this->formValues['translations'][$localeCode]['slug'] = $this->slugGenerator->generate($this->formValues['translations'][$localeCode]['name']); + } + + /** + * @return array + */ + public function hydrateAttributesToBeAdded(string $value): array + { + if ('' === $value) { + return []; + } + + return explode(',', $value); + } + + /** + * @param array $value + */ + public function dehydrateAttributesToBeAdded(array $value): string + { + return implode(',', $value); + } + + public function dehydrateFormData(): ?int + { + return $this->resource?->getId(); + } + + private function getDataModelValue(): string + { + return 'norender|*'; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/GenerateProductVariantsFormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/GenerateProductVariantsFormComponent.php new file mode 100644 index 0000000000..8f0f62a54e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/GenerateProductVariantsFormComponent.php @@ -0,0 +1,46 @@ +formFactory->create($this->formClass, $this->resource); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/ProductAttributeAutocompleteComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/ProductAttributeAutocompleteComponent.php new file mode 100644 index 0000000000..a8d18e310b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Product/ProductAttributeAutocompleteComponent.php @@ -0,0 +1,70 @@ + */ + #[LiveProp(writable: true, hydrateWith: 'hydrateSelectedAttributeCodes', dehydrateWith: 'dehydrateSelectedAttributeCodes', updateFromParent: true)] + public array $selectedAttributeCodes = []; + + /** @var array */ + #[LiveProp(updateFromParent: true)] + public array $excludedAttributeCodes = []; + + use ComponentToolsTrait; + use DefaultActionTrait; + + public function __construct( + private readonly ChecksumCalculator $checksumCalculator, + ) { + } + + #[ExposeInTemplate] + public function getExtraOptions(): string + { + return base64_encode(json_encode( + [ + 'attributeCodes' => $this->excludedAttributeCodes, + '@checksum' => $this->checksumCalculator->calculateForArray(['attributeCodes' => $this->excludedAttributeCodes]), + ], + )); + } + + /** + * @return array + */ + public function hydrateSelectedAttributeCodes(string $value): array + { + if ('' === $value) { + return []; + } + + return explode(',', $value); + } + + /** + * @param array $value + */ + public function dehydrateSelectedAttributeCodes(array $value): string + { + return implode(',', $value); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Promotion/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Promotion/FormComponent.php new file mode 100644 index 0000000000..07c183115e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Promotion/FormComponent.php @@ -0,0 +1,73 @@ +fieldNameToPropertyPath($name, $this->formName); + $data = $propertyAccessor->getValue($this->formValues, $propertyPath); + + if (!\is_array($data)) { + $propertyAccessor->setValue($this->formValues, $propertyPath, []); + $data = []; + } + + $propertyAccessor->setValue( + $this->formValues, + sprintf('%s[%s]', $propertyPath, $this->resolveItemIndex($data)), + ['type' => $type], + ); + } + + protected function instantiateForm(): FormInterface + { + return $this->formFactory->create($this->formClass, $this->resource); + } + + /** @param array> $data */ + private function resolveItemIndex(array $data): int + { + return [] !== $data ? max(array_keys($data)) + 1 : 0; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Shared/Navbar/NotificationsComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Shared/Navbar/NotificationsComponent.php new file mode 100644 index 0000000000..b0b32c6a4d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Shared/Navbar/NotificationsComponent.php @@ -0,0 +1,28 @@ + + */ + #[ExposeInTemplate] + public function getNotifications(): array + { + return []; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Shared/Navbar/UserDropdownComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Shared/Navbar/UserDropdownComponent.php new file mode 100644 index 0000000000..81cfb26916 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Shared/Navbar/UserDropdownComponent.php @@ -0,0 +1,90 @@ +security->getUser(); + + if (!$user instanceof UserInterface) { + throw new \RuntimeException('User must be an instance of Sylius\Component\User\Model\UserInterface'); + } + + return $user; + } + + /** + * @return array> + * + * @psalm-suppress InvalidReturnType + */ + #[ExposeInTemplate] + public function getMenuItems(): array + { + /** + * @phpstan-ignore-next-line PHPStan complains the declared return type does not match the returned value + * + * @psalm-suppress InvalidReturnStatement + */ + return [ + [ + 'title' => $this->translator->trans('sylius.ui.my_account'), + 'url' => $this->urlGenerator->generate('sylius_admin_admin_user_update', ['id' => $this->getUser()->getId()]), + 'icon' => 'user', + ], + [ + 'title' => $this->translator->trans('sylius.ui.logout'), + 'url' => $this->urlGenerator->generate('sylius_admin_logout'), + 'icon' => 'logout', + 'attr' => [ + 'data-test-logout' => null, + ], + ], + [ + 'type' => 'divider', + ], + [ + 'title' => $this->translator->trans('sylius.ui.documentation'), + 'url' => 'https://docs.sylius.com', + 'class' => 'small text-muted', + ], + [ + 'title' => $this->translator->trans('sylius.ui.join_slack'), + 'url' => 'https://sylius.com/slack', + 'class' => 'small text-muted', + ], + [ + 'title' => $this->translator->trans('sylius.ui.report_an_issue'), + 'url' => 'https://github.com/Sylius/Sylius/issues', + 'class' => 'small text-muted', + ], + ]; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Shipment/ShipFormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Shipment/ShipFormComponent.php new file mode 100644 index 0000000000..b2ef3447ec --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Shipment/ShipFormComponent.php @@ -0,0 +1,51 @@ +formFactory->create($this->formClass, $this->shipment); + } + + protected function getDataModelValue(): string + { + return 'norender|*'; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/ShippingMethod/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/ShippingMethod/FormComponent.php new file mode 100644 index 0000000000..3a76685d37 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/ShippingMethod/FormComponent.php @@ -0,0 +1,72 @@ +fieldNameToPropertyPath($name, $this->formName); + $data = $propertyAccessor->getValue($this->formValues, $propertyPath); + + if (!\is_array($data)) { + $propertyAccessor->setValue($this->formValues, $propertyPath, []); + $data = []; + } + + $propertyAccessor->setValue( + $this->formValues, + sprintf('%s[%s]', $propertyPath, $this->resolveItemIndex($data)), + ['type' => $type], + ); + } + + protected function instantiateForm(): FormInterface + { + return $this->formFactory->create($this->shippingMethodTypeClass, $this->resource); + } + + /** @param array> $data */ + private function resolveItemIndex(array $data): int + { + return [] !== $data ? max(array_keys($data)) + 1 : 0; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Taxon/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Taxon/FormComponent.php new file mode 100644 index 0000000000..dac98b7552 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Taxon/FormComponent.php @@ -0,0 +1,46 @@ +formFactory->create($this->formClass, $this->resource); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Taxon/TreeComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Taxon/TreeComponent.php new file mode 100644 index 0000000000..41860b0d4f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Taxon/TreeComponent.php @@ -0,0 +1,76 @@ + $taxonRepository + */ + public function __construct( + private readonly TaxonRepositoryInterface $taxonRepository, + private readonly ObjectManager $taxonManager, + ) { + } + + /** + * @return array + */ + #[ExposeInTemplate] + public function getRootNodes(): array + { + return $this->taxonRepository->findHydratedRootNodes(); + } + + #[LiveAction] + public function moveUp(#[LiveArg] int $taxonId): void + { + $taxonToBeMoved = $this->taxonRepository->find($taxonId); + + if ($taxonToBeMoved->getPosition() > 0) { + $taxonToBeMoved->setPosition($taxonToBeMoved->getPosition() - 1); + $this->taxonManager->flush(); + } + } + + #[LiveAction] + public function moveDown(#[LiveArg] int $taxonId): void + { + $taxonToBeMoved = $this->taxonRepository->find($taxonId); + + $taxonToBeMoved->setPosition($taxonToBeMoved->getPosition() + 1); + $this->taxonManager->flush(); + } + + #[LiveAction] + public function delete(#[LiveArg] int $taxonId): void + { + $taxon = $this->taxonRepository->find($taxonId); + $this->taxonRepository->remove($taxon); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/Component/Zone/FormComponent.php b/src/Sylius/Bundle/AdminBundle/Twig/Component/Zone/FormComponent.php new file mode 100644 index 0000000000..b9c03f3580 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/Component/Zone/FormComponent.php @@ -0,0 +1,51 @@ +zone->setType($this->type); + + return $this->formFactory->create($this->formClass, $this->zone, ['add_build_zone_form_subscriber' => false]); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/GridExtension.php b/src/Sylius/Bundle/AdminBundle/Twig/GridExtension.php new file mode 100644 index 0000000000..c30cbcfb0d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/GridExtension.php @@ -0,0 +1,36 @@ + + */ + public function getFunctions(): array + { + return [ + new TwigFunction('sylius_grid_render_item_action', [$this->gridRenderer, 'renderItemAction'], ['is_safe' => ['html']]), + ]; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/PaymentMethodExtension.php b/src/Sylius/Bundle/AdminBundle/Twig/PaymentMethodExtension.php new file mode 100644 index 0000000000..4d03395c5c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/PaymentMethodExtension.php @@ -0,0 +1,42 @@ + $gatewayFactories + */ + public function __construct(private readonly array $gatewayFactories) + { + } + + public function getFunctions(): array + { + return [ + new TwigFunction('sylius_admin_get_payment_gateways', [$this, 'getPaymentGateways']), + ]; + } + + /** + * @return array + */ + public function getPaymentGateways(): array + { + return $this->gatewayFactories; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/Twig/PromotionLabelsExtension.php b/src/Sylius/Bundle/AdminBundle/Twig/PromotionLabelsExtension.php new file mode 100644 index 0000000000..4f949fd956 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/Twig/PromotionLabelsExtension.php @@ -0,0 +1,48 @@ + $ruleTypes + * @param array $actionTypes + */ + public function __construct( + private readonly array $ruleTypes, + private readonly array $actionTypes, + ) { + } + + public function getFunctions(): array + { + return [ + new TwigFunction('sylius_admin_get_promotion_action_label', [$this, 'getPromotionActionLabel']), + new TwigFunction('sylius_admin_get_promotion_rule_label', [$this, 'getPromotionRuleLabel']), + ]; + } + + public function getPromotionActionLabel(string $type): string + { + return $this->actionTypes[$type] ?? ''; + } + + public function getPromotionRuleLabel(string $type): string + { + return $this->ruleTypes[$type] ?? ''; + } +} diff --git a/src/Sylius/Bundle/AdminBundle/composer.json b/src/Sylius/Bundle/AdminBundle/composer.json index 6529a93ae9..ebe8ecb532 100644 --- a/src/Sylius/Bundle/AdminBundle/composer.json +++ b/src/Sylius/Bundle/AdminBundle/composer.json @@ -35,10 +35,14 @@ "knplabs/knp-menu-bundle": "^3.0", "sylius/core-bundle": "^2.0", "sylius/ui-bundle": "^2.0", + "sylius/twig-hooks": "~0.2.4", "symfony/framework-bundle": "^6.4.1", + "symfony/stimulus-bundle": "^2.12", + "symfony/ux-autocomplete": "^2.17", + "symfony/ux-live-component": "^2.17", "symfony/webpack-encore-bundle": "^1.17.1", - "twig/intl-extra": "^2.12 || ^3.4", - "twig/twig": "^2.12 || ^3.3" + "twig/extra-bundle": "~3.8.0", + "twig/twig": "~3.8.0" }, "require-dev": { "matthiasnoback/symfony-dependency-injection-test": "^4.2", @@ -49,9 +53,6 @@ "symfony/dependency-injection": "^6.4.1", "symfony/dotenv": "^6.4.0" }, - "conflict": { - "twig/twig": "3.9.0" - }, "config": { "allow-plugins": { "symfony/flex": true diff --git a/src/Sylius/Bundle/AdminBundle/index.js b/src/Sylius/Bundle/AdminBundle/index.js new file mode 100644 index 0000000000..271bd32047 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/index.js @@ -0,0 +1,46 @@ +/* + * 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. + */ + +const path = require('path'); +const Encore = require('@symfony/webpack-encore'); + +class SyliusAdmin { + static getWebpackConfig(rootDir) { + const uiBundleScripts = path.resolve(__dirname, '../UiBundle/Resources/private/js/'); + const uiBundleResources = path.resolve(__dirname, '../UiBundle/Resources/private/'); + + Encore + .setOutputPath('public/build/admin/') + .setPublicPath('/build/admin') + .addEntry('admin-entry', path.resolve(__dirname, 'Resources/assets/entrypoint.js')) + .addEntry('admin-product-entry', path.resolve(__dirname, 'Resources/assets/product-entrypoint.js')) + .disableSingleRuntimeChunk() + .cleanupOutputBeforeBuild() + .enableSourceMaps(!Encore.isProduction()) + .enableVersioning(Encore.isProduction()) + .enableSassLoader((options) => { + // eslint-disable-next-line no-param-reassign + options.additionalData = `$rootDir: ${rootDir};`; + }) + .enableStimulusBridge(path.resolve(__dirname, 'Resources/assets/controllers.json')); + + const adminConfig = Encore.getWebpackConfig(); + + adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts; + adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; + adminConfig.externals = { ...adminConfig.externals, window: 'window', document: 'document' }; + adminConfig.name = 'admin'; + + Encore.reset(); + + return adminConfig; + } +} + +module.exports = SyliusAdmin; diff --git a/src/Sylius/Bundle/AdminBundle/package.json b/src/Sylius/Bundle/AdminBundle/package.json new file mode 100644 index 0000000000..4c00ca086e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/package.json @@ -0,0 +1,31 @@ +{ + "name": "@sylius-ui/admin", + "version": "1.0.0", + "license": "MIT", + "author": "Sylius Sp. z o.o.", + "dependencies": { + "@hotwired/stimulus": "^3.0.0", + "@popperjs/core": "^2.11.8", + "@symfony/stimulus-bridge": "^3.2.2", + "@symfony/webpack-encore": "^3.1.0", + "@tabler/core": "tabler/tabler#dev", + "apexcharts": "^3.41.0", + "bootstrap": "^5.3.0", + "choices.js": "^10.2.0", + "slugify": "^1.6", + "stimulus-use": "^0.52" + }, + "devDependencies": { + "sass": "^1.54.8", + "sass-loader": "^13.0.0" + }, + "engines": { + "node": "^18 || ^20" + }, + "engineStrict": true, + "main": "index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/Sylius/SyliusAdminBundle.git" + } +} diff --git a/src/Sylius/Bundle/AdminBundle/spec/Form/DataTransformer/ProductsToProductAssociationsTransformerSpec.php b/src/Sylius/Bundle/AdminBundle/spec/Form/DataTransformer/ProductsToProductAssociationsTransformerSpec.php new file mode 100644 index 0000000000..2def195a31 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/spec/Form/DataTransformer/ProductsToProductAssociationsTransformerSpec.php @@ -0,0 +1,83 @@ +beConstructedWith( + $productAssociationFactory, + $productAssociationTypeRepository, + ); + } + + function it_is_a_data_transformer(): void + { + $this->shouldImplement(DataTransformerInterface::class); + } + + function it_transforms_an_empty_collection_to_an_empty_array(): void + { + $this->transform(new ArrayCollection())->shouldReturn([]); + } + + function it_transforms_product_associations_to_array( + ProductAssociationInterface $productAssociation, + ProductAssociationTypeInterface $productAssociationType, + ProductInterface $firstAssociatedProduct, + ProductInterface $secondAssociatedProduct, + ): void { + $productAssociation->getType()->willReturn($productAssociationType); + $productAssociation->getAssociatedProducts()->willReturn( + new ArrayCollection([ + $firstAssociatedProduct->getWrappedObject(), + $secondAssociatedProduct->getWrappedObject(), + ]), + ); + + $firstAssociatedProduct->getCode()->willReturn('FIRST'); + $secondAssociatedProduct->getCode()->willReturn('SECOND'); + + $productAssociationType->getCode()->willReturn('accessories'); + + $this->transform(new ArrayCollection([$productAssociation->getWrappedObject()]))->shouldBeLike([ + 'accessories' => new ArrayCollection([ + $firstAssociatedProduct->getWrappedObject(), + $secondAssociatedProduct->getWrappedObject(), + ]), + ]); + } + + function it_reverse_transforms_null_into_null(): void + { + $this->reverseTransform(null)->shouldReturn(null); + } + + function it_reverse_transforms_empty_string_into_null(): void + { + $this->reverseTransform('')->shouldReturn(null); + } +} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections.html.twig new file mode 100644 index 0000000000..7a69be0dc6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections.html.twig @@ -0,0 +1,5 @@ +
+ {% hook 'sections' %} + + {{ form_row(hookable_metadata.context.form._token) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account.html.twig new file mode 100644 index 0000000000..e602d30f22 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account.html.twig @@ -0,0 +1,12 @@ +
+
+
+
+ {{ 'sylius.ui.account'|trans }} +
+
+
+ {% hook 'account' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/email.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/email.html.twig new file mode 100644 index 0000000000..fab6f29d96 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/email.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.email) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/enabled.html.twig new file mode 100644 index 0000000000..12db2f2af2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/enabled.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.enabled) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/password.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/password.html.twig new file mode 100644 index 0000000000..469765f1cc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/password.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.plainPassword) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/username.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/username.html.twig new file mode 100644 index 0000000000..6bea6044fd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/account/username.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.username) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information.html.twig new file mode 100644 index 0000000000..5d3bcc0e2b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information.html.twig @@ -0,0 +1,12 @@ +
+
+
+
+ {{ 'sylius.ui.personal_information'|trans }} +
+
+
+ {% hook 'personal_information' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/avatar.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/avatar.html.twig new file mode 100644 index 0000000000..64432db188 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/avatar.html.twig @@ -0,0 +1,32 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set adminUser = hookable_metadata.context.resource %} + +{{ form_label(hookable_metadata.context.form.avatar) }} + +
+
+ {% if adminUser.avatar is not null and adminUser.avatar.path is not empty %} +
+ {% else %} +
+ {% endif %} +
+
+ {{ form_widget(hookable_metadata.context.form.avatar) }} + {% if adminUser.id is not null and adminUser.avatar is not null and adminUser.avatar.path is not empty %} + + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/first_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/first_name.html.twig new file mode 100644 index 0000000000..889f61b716 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/first_name.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.firstName) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/last_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/last_name.html.twig new file mode 100644 index 0000000000..66120033ac --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/last_name.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.lastName) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/locale.html.twig b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/locale.html.twig new file mode 100644 index 0000000000..be5c60ca07 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/admin_user/form/sections/personal_information/locale.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.localeCode, sylius_test_form_attribute('admin-locale-switch')) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/active.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/active.html.twig new file mode 100644 index 0000000000..4ccae500f4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/active.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.active'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/failed.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/failed.html.twig new file mode 100644 index 0000000000..fe3f039a82 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/failed.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.failed'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/inactive.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/inactive.html.twig new file mode 100644 index 0000000000..4642a5442b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/inactive.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.inactive'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/processing.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/processing.html.twig new file mode 100644 index 0000000000..73cc86d08f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/common/label/state/processing.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.processing'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form.html.twig new file mode 100644 index 0000000000..70c22618cf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form.html.twig @@ -0,0 +1,16 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\CatalogPromotion\FormComponent #} + +{% form_theme form '@SyliusAdmin/catalog_promotion/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: hookable.configuration.render_rest|default(false)}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections.html.twig new file mode 100644 index 0000000000..86a74da537 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections.html.twig @@ -0,0 +1 @@ +{% hook 'sections' %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration.html.twig new file mode 100644 index 0000000000..4f4e6ca114 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration.html.twig @@ -0,0 +1,18 @@ +
+
+
+ {{ 'sylius.ui.configuration'|trans }} +
+
+
+
+
+ {% hook 'configuration#left' %} +
+ +
+ {% hook 'configuration#right' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/enabled.html.twig new file mode 100644 index 0000000000..3a60a55c79 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/enabled.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.enabled) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/end_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/end_date.html.twig new file mode 100644 index 0000000000..09df903cee --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/end_date.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.endDate) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/exclusive.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/exclusive.html.twig new file mode 100644 index 0000000000..3eb8fb3ace --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/exclusive.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.exclusive) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/header.html.twig new file mode 100644 index 0000000000..923f5d4a1c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/header.html.twig @@ -0,0 +1 @@ +
{{ 'sylius.ui.options'|trans }}
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/priority.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/priority.html.twig new file mode 100644 index 0000000000..2906136b50 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/priority.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.priority) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/start_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/start_date.html.twig new file mode 100644 index 0000000000..171bd2d93d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/configuration/start_date.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.startDate) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general.html.twig new file mode 100644 index 0000000000..85638eb426 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general.html.twig @@ -0,0 +1,12 @@ +
+
+
+ {{ 'sylius.ui.general'|trans }} +
+
+
+
+ {% hook 'general' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/channels.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/channels.html.twig new file mode 100644 index 0000000000..a6f41e2711 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/channels.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.channels) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/code.html.twig new file mode 100644 index 0000000000..69861ccd02 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/code.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.code) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/name.html.twig new file mode 100644 index 0000000000..ff93f7b852 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/general/name.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.name) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions.html.twig new file mode 100644 index 0000000000..80218fd6d4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'scopes_and_actions' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions/actions.html.twig new file mode 100644 index 0000000000..67489889e5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions/actions.html.twig @@ -0,0 +1,19 @@ +
+
+
+
+ {{ 'sylius.ui.actions'|trans }} +
+
+
+
+ {{ form_row(hookable_metadata.context.form.actions, {label: false}) }} + + {% hook 'actions' %} +
+
+ +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions/scopes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions/scopes.html.twig new file mode 100644 index 0000000000..a01c48708d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/scopes_and_actions/scopes.html.twig @@ -0,0 +1,19 @@ +
+
+
+
+ {{ 'sylius.ui.scopes'|trans }} +
+
+
+
+ {{ form_row(hookable_metadata.context.form.scopes, {label: false}) }} + + {% hook 'scopes' %} +
+
+ +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/translations.html.twig new file mode 100644 index 0000000000..89eccc60db --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form/sections/translations.html.twig @@ -0,0 +1,5 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +
+ {{ _translations.default(hookable_metadata.context.form.translations, null, {accordionId: 'catalog-promotion-translations'}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form_theme.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form_theme.html.twig new file mode 100644 index 0000000000..fa28aa2d97 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/form_theme.html.twig @@ -0,0 +1,38 @@ +{% extends '@SyliusAdmin/shared/form_theme.html.twig' %} + +{%- block live_collection_widget -%} + {{ block('form_widget') }} +{%- endblock live_collection_widget -%} + +{%- block live_collection_entry_row -%} +
+ {{- form_errors(form) -}} + {{- form_row(form.type) -}} +
+
+
{{ ('sylius.ui.' ~ form.type.vars.data)|trans}}
+ {{- form_row(button_delete, sylius_test_form_attribute('delete-action')|sylius_merge_recursive({'attr': {'class': 'btn-close'}})) -}} +
+
+ {{- form_row(form.configuration, {'label': false}) -}} +
+
+
+{%- endblock live_collection_entry_row -%} + +{% block add_button_row %} + {% if types is not empty %} + + {% endif %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/action/delete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/action/delete.html.twig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/date.html.twig new file mode 100644 index 0000000000..2312ff8d6e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/date.html.twig @@ -0,0 +1,8 @@ +
+ {% if data is null %} + - + {% else %} +
{{ data|date('Y-m-d') }}
+
{{ data|date('H:i') }}
+ {% endif %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/priority.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/priority.html.twig new file mode 100644 index 0000000000..aac977dd11 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/priority.html.twig @@ -0,0 +1 @@ +{{ data }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/state.html.twig new file mode 100644 index 0000000000..fa8fac63b3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/grid/field/state.html.twig @@ -0,0 +1 @@ +{{ include('@SyliusAdmin/catalog_promotion/common/label/state/' ~ data ~ '.html.twig') }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..81c22c4bf2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/actions.html.twig @@ -0,0 +1,7 @@ +{% set resource = hookable_metadata.context.resource %} + +
+
+ {% hook 'actions' with { resource } %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/actions/update.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/actions/update.html.twig new file mode 100644 index 0000000000..fd9737d80a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/actions/update.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set resource = hookable_metadata.context.resource %} + + + {{ icon({icon: 'pencil'}) }} + {{ 'sylius.ui.update'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..11a59e0ad7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/header/title_block/title.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +
+
+ {{ _header.h1(hookable_metadata.context.resource.name) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections.html.twig new file mode 100644 index 0000000000..f9aeedbfcf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections.html.twig @@ -0,0 +1,12 @@ +
+
+
+
+ {% hook 'sections#left' %} +
+
+ {% hook 'sections#right' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions.html.twig new file mode 100644 index 0000000000..da2a3c2a6f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions.html.twig @@ -0,0 +1,10 @@ +
+
+
+ {{ 'sylius.ui.actions'|trans }} +
+
+
+ {% hook 'actions' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action.html.twig new file mode 100644 index 0000000000..6931c5e7e8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action.html.twig @@ -0,0 +1,9 @@ +{% for action in hookable_metadata.context.resource.actions %} +
+
+
+ {% hook 'action#' ~ action.type with { action } %} +
+
+
+{% endfor %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/amount.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/amount.html.twig new file mode 100644 index 0000000000..9bdf970449 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/amount.html.twig @@ -0,0 +1,6 @@ +
+
{{ 'sylius.ui.amount'|trans }}
+
+ {{- hookable_metadata.context.action.configuration['amount']|format_number(style='percent') -}} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/channels_amount.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/channels_amount.html.twig new file mode 100644 index 0000000000..7321ef5cfe --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/channels_amount.html.twig @@ -0,0 +1,12 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set currencies = sylius_channels_currencies() %} + +{% for channelCode, channelConfiguration in hookable_metadata.context.action.configuration %} +
+
{{ channelCode }}
+
+ {{ _money.format(channelConfiguration['amount'], currencies[channelCode]) }} +
+
+{% endfor %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/type.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/type.html.twig new file mode 100644 index 0000000000..f717fbd912 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/actions/action/type.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.type'|trans }}
+
{{ hookable_metadata.configuration.type_label|trans }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details.html.twig new file mode 100644 index 0000000000..be1a004130 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details.html.twig @@ -0,0 +1,12 @@ +
+
+
+ {{ 'sylius.ui.details'|trans }} +
+
+
+
+ {% hook 'details' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/channels.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/channels.html.twig new file mode 100644 index 0000000000..bec8ef2ee1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/channels.html.twig @@ -0,0 +1,10 @@ +
+
{{ 'sylius.ui.channels'|trans }}
+
+ {% for channel in hookable_metadata.context.resource.channels %} + + {{ channel.name }} +
+ {% endfor %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/code.html.twig new file mode 100644 index 0000000000..33c04bb061 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/code.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.code'|trans }}
+
{{ hookable_metadata.context.resource.code }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/enabled.html.twig new file mode 100644 index 0000000000..636ec43796 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/enabled.html.twig @@ -0,0 +1,14 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
+
{{ 'sylius.ui.enabled'|trans }}
+
+ + {% if hookable_metadata.context.resource.enabled %} + {{ _icon({icon: 'check', class: 'icon text-green'}) }} + {% else %} + {{ _icon({icon: 'x', class: 'icon icon-sm text-secondary'}) }} + {% endif %} + +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/end_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/end_date.html.twig new file mode 100644 index 0000000000..44788e11d7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/end_date.html.twig @@ -0,0 +1,8 @@ +{% set date_format = hookable_metadata.configuration.date_format|default('YYYY-MM-dd HH:mm:ss') %} + +
+
{{ 'sylius.ui.end_date'|trans }}
+
+ {{ hookable_metadata.context.resource.endDate|format_datetime(pattern=date_format) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/exclusive.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/exclusive.html.twig new file mode 100644 index 0000000000..4eb54ae07f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/exclusive.html.twig @@ -0,0 +1,14 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
+
{{ 'sylius.ui.exclusive'|trans }}
+
+ + {% if hookable_metadata.context.resource.exclusive %} + {{ _icon({icon: 'check', class: 'icon text-green'}) }} + {% else %} + {{ _icon({icon: 'x', class: 'icon icon-sm text-secondary'}) }} + {% endif %} + +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/name.html.twig new file mode 100644 index 0000000000..18f06b915f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/name.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.name'|trans }}
+
{{ hookable_metadata.context.resource.name }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/priority.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/priority.html.twig new file mode 100644 index 0000000000..925ada7ab1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/priority.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.priority'|trans }}
+
{{ hookable_metadata.context.resource.priority }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/start_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/start_date.html.twig new file mode 100644 index 0000000000..16398f43a7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/start_date.html.twig @@ -0,0 +1,8 @@ +{% set date_format = hookable_metadata.configuration.date_format|default('YYYY-MM-dd HH:mm:ss') %} + +
+
{{ 'sylius.ui.start_date'|trans }}
+
+ {{ hookable_metadata.context.resource.startDate|format_datetime(pattern=date_format) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/state.html.twig new file mode 100644 index 0000000000..0287bbc65d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/details/state.html.twig @@ -0,0 +1,6 @@ +
+
{{ 'sylius.ui.state'|trans }}
+
+ {{ include('@SyliusAdmin/catalog_promotion/common/label/state/' ~ hookable_metadata.context.resource.state ~ '.html.twig') }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes.html.twig new file mode 100644 index 0000000000..34feb2c82b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes.html.twig @@ -0,0 +1,10 @@ +
+
+
+ {{ 'sylius.ui.scopes'|trans }} +
+
+
+ {% hook 'scopes' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope.html.twig new file mode 100644 index 0000000000..34f82a9439 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope.html.twig @@ -0,0 +1,9 @@ +{% for scope in hookable_metadata.context.resource.scopes %} +
+
+
+ {% hook 'scope#' ~ scope.type with { scope } %} +
+
+
+{% endfor %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope/list.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope/list.html.twig new file mode 100644 index 0000000000..b342d2b2ee --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope/list.html.twig @@ -0,0 +1,10 @@ +
+
{{ hookable_metadata.configuration.label|trans }}
+
+
    + {% for item in hookable_metadata.context.scope.configuration[hookable_metadata.configuration.items_key] %} +
  • {{ item }}
  • + {% endfor %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope/type.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope/type.html.twig new file mode 100644 index 0000000000..f717fbd912 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/scopes/scope/type.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.type'|trans }}
+
{{ hookable_metadata.configuration.type_label|trans }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations.html.twig new file mode 100644 index 0000000000..bcbfe8c91e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations.html.twig @@ -0,0 +1,31 @@ +{% set catalogPromotion = hookable_metadata.context.resource %} + +
+
+ {% for translation in catalogPromotion.translations %} + {% set locale = translation.locale %} + +
+

+ +

+
+
+
+
+
+
+ {% hook 'translations' with { translation } %} +
+
+
+
+
+
+
+ {% endfor %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations/description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations/description.html.twig new file mode 100644 index 0000000000..ef87e73584 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations/description.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.description'|trans }}
+
{{ hookable_metadata.context.translation.description }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations/label.html.twig b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations/label.html.twig new file mode 100644 index 0000000000..3799a676d1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/catalog_promotion/show/content/sections/translations/label.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.label'|trans }}
+
{{ hookable_metadata.context.translation.label }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form.html.twig new file mode 100644 index 0000000000..4005a6d0e2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form.html.twig @@ -0,0 +1,15 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\Channel\FormComponent #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + {{ form_end(form, {render_rest: false}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections.html.twig new file mode 100644 index 0000000000..86a74da537 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections.html.twig @@ -0,0 +1 @@ +{% hook 'sections' %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general.html.twig new file mode 100644 index 0000000000..d071e7f60d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general.html.twig @@ -0,0 +1,11 @@ +
+
+
{{ 'sylius.ui.general'|trans }}
+
+ +
+
+ {% hook 'general' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/account_verification_required.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/account_verification_required.html.twig new file mode 100644 index 0000000000..ab1d9d30a1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/account_verification_required.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.accountVerificationRequired, sylius_test_form_attribute('account-verification-required')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/address_required_in_checkout.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/address_required_in_checkout.html.twig new file mode 100644 index 0000000000..f1b2e5a8fa --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/address_required_in_checkout.html.twig @@ -0,0 +1,5 @@ +
+
+ {{ form_row(hookable_metadata.context.form.shippingAddressInCheckoutRequired) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/code.html.twig new file mode 100644 index 0000000000..518fdc022a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/code.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/color.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/color.html.twig new file mode 100644 index 0000000000..446c3303bc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/color.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.color, sylius_test_form_attribute('color')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/contact_email.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/contact_email.html.twig new file mode 100644 index 0000000000..c97a8398ce --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/contact_email.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.contactEmail, sylius_test_form_attribute('contact-email')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/contact_phone_number.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/contact_phone_number.html.twig new file mode 100644 index 0000000000..2f951a1f7a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/contact_phone_number.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.contactPhoneNumber, sylius_test_form_attribute('contact-phone-number')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/countries.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/countries.html.twig new file mode 100644 index 0000000000..38372d1336 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/countries.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.countries, sylius_test_form_attribute('countries')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/description.html.twig new file mode 100644 index 0000000000..a65a120fed --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/description.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.description, sylius_test_form_attribute('description')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/enabled.html.twig new file mode 100644 index 0000000000..3cfd6ea4d1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/enabled.html.twig @@ -0,0 +1,5 @@ +
+
+ {{ form_row(hookable_metadata.context.form.enabled, sylius_test_form_attribute('enabled')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/hostname.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/hostname.html.twig new file mode 100644 index 0000000000..339fdfea0b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/hostname.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.hostname, sylius_test_form_attribute('hostname')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/name.html.twig new file mode 100644 index 0000000000..73b685c34f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/name.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.name, sylius_test_form_attribute('name')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/skip_payment_step.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/skip_payment_step.html.twig new file mode 100644 index 0000000000..9b1b205168 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/skip_payment_step.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.skippingPaymentStepAllowed, sylius_test_form_attribute('skipping-payment-step-allowed')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/skip_shipping_step.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/skip_shipping_step.html.twig new file mode 100644 index 0000000000..f15eb0f3b3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/general/skip_shipping_step.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.skippingShippingStepAllowed, sylius_test_form_attribute('skipping-shipping-step-allowed')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel.html.twig new file mode 100644 index 0000000000..e5b767f3f6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel.html.twig @@ -0,0 +1,11 @@ +
+
+
{{ 'sylius.ui.look_and_feel'|trans }}
+
+ +
+
+ {% hook 'look_and_feel' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/default_locale.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/default_locale.html.twig new file mode 100644 index 0000000000..2a4039c3b2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/default_locale.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.defaultLocale, sylius_test_form_attribute('default-locale')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/locales.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/locales.html.twig new file mode 100644 index 0000000000..d4201bb709 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/locales.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.locales, sylius_test_form_attribute('locales')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/menu_taxon.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/menu_taxon.html.twig new file mode 100644 index 0000000000..2d01d15494 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/menu_taxon.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.menuTaxon, sylius_test_form_attribute('menu-taxon')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/theme.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/theme.html.twig new file mode 100644 index 0000000000..3926a7340e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/look_and_feel/theme.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.themeName, sylius_test_form_attribute('theme')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money.html.twig new file mode 100644 index 0000000000..bd2bcea822 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money.html.twig @@ -0,0 +1,11 @@ +
+
+
{{ 'sylius.ui.money'|trans }}
+
+ +
+
+ {% hook 'money' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/base_currency.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/base_currency.html.twig new file mode 100644 index 0000000000..5376e2fa21 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/base_currency.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.baseCurrency, sylius_test_form_attribute('base-currency')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/currencies.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/currencies.html.twig new file mode 100644 index 0000000000..37837be0d1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/currencies.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.currencies, sylius_test_form_attribute('currencies')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/default_tax_zone.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/default_tax_zone.html.twig new file mode 100644 index 0000000000..2dde26f03a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/default_tax_zone.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.defaultTaxZone, sylius_test_form_attribute('default-tax-zone')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/tax_calculation_strategy.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/tax_calculation_strategy.html.twig new file mode 100644 index 0000000000..60e4e01675 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/money/tax_calculation_strategy.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.taxCalculationStrategy, sylius_test_form_attribute('tax-calculation-strategy')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus.html.twig new file mode 100644 index 0000000000..cfdadb40c3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus.html.twig @@ -0,0 +1,11 @@ +
+
+
{{ 'sylius.ui.omnibus'|trans }}
+
+ +
+
+ {% hook 'omnibus' with { form: hookable_metadata.context.form.channelPriceHistoryConfig } %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/lowest_price_checking_period.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/lowest_price_checking_period.html.twig new file mode 100644 index 0000000000..c74a4e88dc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/lowest_price_checking_period.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.lowestPriceForDiscountedProductsCheckingPeriod, sylius_test_form_attribute('lowest-price-for-discounted-products-checking-period')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/show_lowest_price.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/show_lowest_price.html.twig new file mode 100644 index 0000000000..4164b22735 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/show_lowest_price.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.lowestPriceForDiscountedProductsVisible, sylius_test_form_attribute('lowest-price-for-discounted-products-visible')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/taxons_excluded_from_showing_lowest_price.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/taxons_excluded_from_showing_lowest_price.html.twig new file mode 100644 index 0000000000..325bb5b6a3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/omnibus/taxons_excluded_from_showing_lowest_price.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.taxonsExcludedFromShowingLowestPrice, sylius_test_form_attribute('taxons-excluded-from-showing-lowest-price')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data.html.twig new file mode 100644 index 0000000000..d4e74f7204 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data.html.twig @@ -0,0 +1,11 @@ +
+
+
{{ 'sylius.form.channel.shop_billing_data'|trans }}
+
+ +
+
+ {% hook 'shop_billing_data' with { form: hookable_metadata.context.form.shopBillingData } %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/city.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/city.html.twig new file mode 100644 index 0000000000..4934422d7e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/city.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.city, sylius_test_form_attribute('city')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/company.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/company.html.twig new file mode 100644 index 0000000000..ed0de30be8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/company.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.company, sylius_test_form_attribute('company')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/country.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/country.html.twig new file mode 100644 index 0000000000..8b6a478473 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/country.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.countryCode, sylius_test_form_attribute('country')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/postcode.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/postcode.html.twig new file mode 100644 index 0000000000..46202b0708 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/postcode.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.postcode, sylius_test_form_attribute('postcode')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/street.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/street.html.twig new file mode 100644 index 0000000000..7ce61b941d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/street.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.street, sylius_test_form_attribute('street')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/tax_id.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/tax_id.html.twig new file mode 100644 index 0000000000..d981a1ac08 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/form/sections/shop_billing_data/tax_id.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.taxId, sylius_test_form_attribute('tax-id')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/grid/field/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/grid/field/code.html.twig new file mode 100644 index 0000000000..34345bb680 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/grid/field/code.html.twig @@ -0,0 +1 @@ +{{ data|upper }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel/grid/field/theme.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel/grid/field/theme.html.twig new file mode 100644 index 0000000000..5991849817 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel/grid/field/theme.html.twig @@ -0,0 +1,5 @@ +{% if data is empty %} + {{ 'sylius.ui.default'|trans }} +{% else %} + {{ data }} +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ChannelPricingLogEntry/Grid/Field/originalPrice.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/grid/field/original_price.html.twig similarity index 59% rename from src/Sylius/Bundle/AdminBundle/Resources/views/ChannelPricingLogEntry/Grid/Field/originalPrice.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/grid/field/original_price.html.twig index f30b178739..96cf2af273 100644 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ChannelPricingLogEntry/Grid/Field/originalPrice.html.twig +++ b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/grid/field/original_price.html.twig @@ -1,10 +1,10 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} +{% import "@SyliusAdmin/shared/helper/money.html.twig" as _money %} {% set currencies = sylius_channels_currencies() %} {% set channel_code = data.channelPricing.channelCode %} {% if data.originalPrice %} - {{ money.format(data.originalPrice, currencies[channel_code]) }} + {{ _money.format(data.originalPrice, currencies[channel_code]) }} {% else %} - {% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/grid/field/price.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/grid/field/price.html.twig new file mode 100644 index 0000000000..f480734fc1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/grid/field/price.html.twig @@ -0,0 +1,6 @@ +{% import "@SyliusAdmin/shared/helper/money.html.twig" as _money %} + +{% set currencies = sylius_channels_currencies() %} +{% set channel_code = data.channelPricing.channelCode %} + +{{ _money.format(data.price, currencies[channel_code]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/index.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/index.html.twig new file mode 100644 index 0000000000..c029df0255 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/index.html.twig @@ -0,0 +1,4 @@ +{% extends '@SyliusAdmin/shared/crud/index.html.twig' %} + +{% set resource_name = 'channel_pricing_log_entry' %} +{% block title %}{{ 'sylius.ui.channel_pricing_history'|trans }} | {{ parent() }}{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/index/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/index/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..5d5cf3cd48 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/channel_pricing_log_entry/index/content/header/breadcrumbs.html.twig @@ -0,0 +1,15 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set configuration = hookable_metadata.context.resources.requestConfiguration %} + +{% set product_variant = configuration.vars.product_variant %} +{% set product = configuration.vars.product_variant.product %} + +{{ _breadcrumbs.default([ + { name: 'Dashboard', url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index'), active: false }, + { name: product.name|default(product.code), url: path('sylius_admin_product_show', {'id': product.id }), active: false }, + { name: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': product.id }), active: false }, + { name: product_variant.name|default(product_variant.code), url: path('sylius_admin_product_variant_update', {'id': product_variant.id, 'productId': product.id }), active: false }, + { name: 'sylius.ui.price_history'|trans, active: true } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/form.html.twig new file mode 100644 index 0000000000..b0668c0db1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/form.html.twig @@ -0,0 +1,14 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: false}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections.html.twig new file mode 100644 index 0000000000..7589e187bd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'sections' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details.html.twig new file mode 100644 index 0000000000..3fdd050726 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'details' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details/code.html.twig new file mode 100644 index 0000000000..fed599e8cf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details/code.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details/enabled.html.twig new file mode 100644 index 0000000000..2db1db372b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/details/enabled.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.enabled, sylius_test_form_attribute('enabled')|merge({ label_attr: { class: 'checkbox-switch' } })) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/provinces.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/provinces.html.twig new file mode 100644 index 0000000000..0fd0e8266a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/form/sections/provinces.html.twig @@ -0,0 +1,50 @@ +
+
+ + {{ form_label(hookable_metadata.context.form.provinces) }} + {{ form_errors(hookable_metadata.context.form.provinces) }} + +
+ {% for key, provinceForm in hookable_metadata.context.form.provinces %} +
+
+
+
+
+ {{ form_label(provinceForm.code, null, {label_attr: {class: 'col-form-label col-auto'}}) }} +
+ {{ form_widget(provinceForm.code, sylius_test_form_attribute('province-code')) }} + {{ form_errors(provinceForm.code) }} +
+
+
+
+
+ {{ form_label(provinceForm.name, null, {label_attr: {class: 'col-form-label col-auto'}}) }} +
+ {{ form_widget(provinceForm.name, sylius_test_form_attribute('province-name')) }} + {{ form_errors(provinceForm.name) }} +
+
+
+
+
+ {{ form_label(provinceForm.abbreviation, null, {label_attr: {class: 'col-form-label col-auto'}}) }} +
+ {{ form_widget(provinceForm.abbreviation, sylius_test_form_attribute('province-abbreviation')) }} + {{ form_errors(provinceForm.abbreviation) }} +
+
+
+
+ {{ form_row(provinceForm.vars.button_delete, {attr: {class: 'btn btn-outline-danger'}}) }} +
+
+
+
+ {% endfor %} +
+ + {{ form_widget(hookable_metadata.context.form.provinces.vars.button_add, sylius_test_form_attribute('add-province')) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/country/grid/field/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/country/grid/field/name.html.twig new file mode 100644 index 0000000000..80be5e757a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/country/grid/field/name.html.twig @@ -0,0 +1,2 @@ + +{{ data }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/component/order_statistics.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/component/order_statistics.html.twig new file mode 100644 index 0000000000..d6cde62602 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/component/order_statistics.html.twig @@ -0,0 +1,86 @@ +{% from '@SyliusAdmin/shared/helper/accordion.html.twig' import default as _accordion %} +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} +{% from '@SyliusAdmin/shared/helper/money.html.twig' import format as _money %} + +{% set items = [] %} +
+
+
+ {% for channelStatistics in this.statistics %} + {% set channel = channelStatistics.channel %} + + {% set title %} +
+ + {{ channel.name }} +
+ {% endset %} + + {% set content %} +
+
+
+
+
+
+ + {{ _icon({icon: 'shopping-bag'}) }} + +
+
+
{{ 'sylius.ui.orders'|trans }}
+
{{ channelStatistics.ordersCount }}
+
+
+
+
+
+
+
+
+
+
+ + {{ _icon({icon: 'coins'}) }} + +
+
+
{{ 'sylius.ui.total_value_of_orders'|trans }}
+
{{ _money(channelStatistics.ordersValue, channel.baseCurrency.code) }}
+
+
+
+
+
+
+
+
+
+
+ + {{ _icon({icon: 'slash'}) }} + +
+
+
{{ 'sylius.ui.average_order_value'|trans }}
+
{{ _money(channelStatistics.averageOrderValue, channel.baseCurrency.code) }}
+
+
+
+
+
+
+ {% endset %} + + {% set open = loop.first ? true : false %} + {% set items = items|merge([{title: title, content: content, open: open}]) %} + {% endfor %} + + {% if items is not empty %} + {{ _accordion(items, false, null, true) }} + {% else %} +
{{ 'sylius.ui.there_are_no_orders_for_this_customer_to_display'|trans }}
+ {% endif %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..ffaef3a002 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/breadcrumbs.html.twig @@ -0,0 +1,23 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set configuration = hookable_metadata.context.configuration %} +{% set resource = hookable_metadata.context.resource %} + +{% if hookable_metadata.context.metadata is defined %} + {% set metadata = hookable_metadata.context.metadata %} + {% set resourceName = hookable_metadata.configuration.resource_name|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} +{% else %} + {% set resourceName = hookable_metadata.configuration.resource_name %} +{% endif %} + +{% set index_url = path( + configuration.vars.index.route.name|default(configuration.getRouteName('index')), + configuration.vars.index.route.parameters|default(configuration.vars.route.parameters|default({})) +) +%} + +{{ _breadcrumbs.default([ + { name: 'Dashboard', url: path('sylius_admin_dashboard'), active: false }, + { name: metadata.applicationName~'.ui.'~metadata.pluralName, url: index_url, active: false }, + { name: resource.email, active: true }, +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..343a9f0123 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions.html.twig @@ -0,0 +1,10 @@ +
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/delete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/delete.html.twig new file mode 100644 index 0000000000..d97107eefa --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/delete.html.twig @@ -0,0 +1,14 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set user = hookable_metadata.context.resource.user %} + +{% if user != null %} +
+ + + +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/edit.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/edit.html.twig new file mode 100644 index 0000000000..3b0dc19a92 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/edit.html.twig @@ -0,0 +1,6 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + + + {{ _icon({ icon: 'pencil', class: 'icon dropdown-item-icon icon-tabler' }) }} + {{ 'sylius.ui.edit'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/impersonate.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/impersonate.html.twig new file mode 100644 index 0000000000..7d0b7c0acc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/impersonate.html.twig @@ -0,0 +1,14 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set user = hookable_metadata.context.resource.user %} + +{% if user != null %} + + {{ _icon({ icon: 'spy', class: 'icon dropdown-item-icon icon-tabler' }) }} + {{ 'sylius.ui.impersonate'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/show_orders.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/show_orders.html.twig new file mode 100644 index 0000000000..7d75f5267a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/actions/show_orders.html.twig @@ -0,0 +1,6 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + + + {{ _icon({ icon: 'shopping-bag', class: 'icon dropdown-item-icon icon-tabler' }) }} + {{ 'sylius.ui.show_orders'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..6d886162c9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/header/title_block/title.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +
+
+ {{ _header.h1(hookable_metadata.context.resource.fullname) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections.html.twig new file mode 100644 index 0000000000..680e587775 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'sections' with { user: hookable_metadata.context.resource.user|default(null) } %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details.html.twig new file mode 100644 index 0000000000..2606496af6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details.html.twig @@ -0,0 +1,7 @@ +
+
+
+ {% hook 'details' with { customer: hookable_metadata.context.resource } %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/customer_since.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/customer_since.html.twig new file mode 100644 index 0000000000..5a001b0b51 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/customer_since.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.customer_since'|trans }}
+
{{ hookable_metadata.context.customer.createdAt|date('d-m-Y H:i:s') }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/default_address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/default_address.html.twig new file mode 100644 index 0000000000..97a58800c5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/default_address.html.twig @@ -0,0 +1,19 @@ +
+
{{ 'sylius.ui.default_address'|trans }}
+
+ {% if hookable_metadata.context.customer.defaultAddress is not empty %} + {% set address = hookable_metadata.context.customer.defaultAddress %} + + {{ address.fullname }}, + {{ address.street }}, + {{ address.postcode }} + {{ address.city }}, + {{ address|sylius_province_name|default('') }} + + {{ address.countryCode|sylius_country_name }} + + {% else %} + {{ 'sylius.ui.this_customer_does_not_have_a_default_address'|trans }} + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/email.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/email.html.twig new file mode 100644 index 0000000000..e4b75efa6f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/email.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
+
{{ 'sylius.ui.email'|trans }}
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/email_verified.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/email_verified.html.twig new file mode 100644 index 0000000000..8b7d87d9f7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/email_verified.html.twig @@ -0,0 +1,16 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set user = hookable_metadata.context.user|default(null) %} + +
+
{{ 'sylius.ui.email_verified'|trans }}
+
+ + {% if user != null and user.verifiedAt != null %} + {{ _icon({icon: 'check', class: 'icon text-green'}) }} + {% else %} + {{ _icon({icon: 'x', class: 'icon icon-sm text-secondary'}) }} + {% endif %} + +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/first_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/first_name.html.twig new file mode 100644 index 0000000000..7a0564dfd9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/first_name.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.first_name'|trans }}
+
{{ hookable_metadata.context.customer.firstName }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/group_membership.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/group_membership.html.twig new file mode 100644 index 0000000000..edcfce425b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/group_membership.html.twig @@ -0,0 +1,10 @@ +
+
{{ 'sylius.ui.group_membership'|trans }}
+
+ {% if hookable_metadata.context.customer.group is not empty %} + {{ hookable_metadata.context.customer.group.name }} + {% else %} + - + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/last_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/last_name.html.twig new file mode 100644 index 0000000000..bb3c0393a7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/last_name.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.last_name'|trans }}
+
{{ hookable_metadata.context.customer.lastName }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/phone.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/phone.html.twig new file mode 100644 index 0000000000..ef284454cb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/phone.html.twig @@ -0,0 +1,10 @@ +
+
{{ 'sylius.ui.phone'|trans }}
+
+ {% if hookable_metadata.context.customer.phoneNumber is not empty %} + {{ hookable_metadata.context.customer.phoneNumber }} + {% else %} + - + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/subscribed_to_newsletter.html.twig b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/subscribed_to_newsletter.html.twig new file mode 100644 index 0000000000..1dee6de6ed --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/customer/show/content/sections/details/subscribed_to_newsletter.html.twig @@ -0,0 +1,14 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
+
{{ 'sylius.ui.subscribed_to_newsletter'|trans }}
+
+ + {% if hookable_metadata.context.customer.subscribedToNewsletter %} + {{ _icon({icon: 'check', class: 'icon text-green'}) }} + {% else %} + {{ _icon({icon: 'x', class: 'icon icon-sm text-secondary'}) }} + {% endif %} + +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index.html.twig new file mode 100644 index 0000000000..64cc2515e0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index.html.twig @@ -0,0 +1,11 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% block title %} + {{ 'sylius.ui.dashboard'|trans }} {{ parent() }} +{% endblock %} + +{% block body %} + {% hook ['sylius_admin.dashboard.index', 'sylius_admin.common.index'] with { + channelCode: channel.code, + } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/new_customers.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/new_customers.html.twig new file mode 100644 index 0000000000..47b6166d59 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/new_customers.html.twig @@ -0,0 +1,48 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +
+
+
+

{{ 'sylius.ui.new_customers'|trans }}

+
+
+ + + + + + + + + {% for customer in newCustomers %} + + + + + {% endfor %} + + + + + + +
Customer
+
+
+ + {{ customer.firstName|first }}{{ customer.lastName|first }} + +
+
+
{{ customer.firstName }} {{ customer.lastName }}
+
{{ customer.email }}
+
+
+
+ + {{ icon({ icon: action.icon|default('eye'), class: 'icon icon-tabler' }) }} + +
{{ 'sylius.ui.show_all'|trans }}
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/new_orders.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/new_orders.html.twig new file mode 100644 index 0000000000..f33f3e1789 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/new_orders.html.twig @@ -0,0 +1,52 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +
+
+
+

{{ 'sylius.ui.new_orders'|trans }}

+
+
+ + + + + + + + + + + {% for order in newOrders %} + + + + + + + {% endfor %} + + + + + + +
{{ 'sylius.ui.customer'|trans }}{{ 'sylius.ui.items'|trans }}{{ 'sylius.ui.total'|trans }}
+
+
+ + {{ order.customer.firstName|first }}{{ order.customer.lastName|first }} + +
+
+
{{ order.customer.firstName }} {{ order.customer.lastName }}
+
{{ order.customer.email }}
+
+
+
{{ order.items|length }}{{ order.total|sylius_format_money(order.currencyCode, order.localeCode) }} + + {{ icon({ icon: action.icon|default('eye'), class: 'icon icon-tabler' }) }} + +
{{ 'sylius.ui.show_all'|trans }}
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/statistics.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/statistics.html.twig new file mode 100644 index 0000000000..c0871d88d2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/component/statistics.html.twig @@ -0,0 +1,6 @@ +
+ {% hook 'statistics' with { + statisticsData: statistics, + range, + } %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..ba78ade5d0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/header/breadcrumbs.html.twig @@ -0,0 +1,5 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{{ _breadcrumbs.default([ + { 'name': 'Dashboard', 'active': true }, +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..c818c06cee --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/header/title_block/title.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +
+
+ {{ _header.h1('sylius.ui.dashboard'|trans) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/latest_statistics.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/latest_statistics.html.twig new file mode 100644 index 0000000000..58c3027e92 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/latest_statistics.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'latest_statistics' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_chart.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_chart.html.twig new file mode 100644 index 0000000000..32a5fc57ed --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_chart.html.twig @@ -0,0 +1,54 @@ +{% set statisticsData = hookable_metadata.context.statisticsData %} +{% set rangeName = hookable_metadata.context.range %} + +
+
+
+ Loading +
+
+ +
+
+
+ + + +
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid.html.twig new file mode 100644 index 0000000000..8e9c0a1438 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'statistics_grid' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/average_order_value.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/average_order_value.html.twig new file mode 100644 index 0000000000..c76f8d2f89 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/average_order_value.html.twig @@ -0,0 +1,26 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set statisticsData = hookable_metadata.context.statisticsData %} + +
+
+
+
+ Loading +
+
+
+
+
+ + {{ _icon({ icon: 'slash' }) }} + +
+
+
{{ 'sylius.ui.average_order_value'|trans }}
+
{{ _context.statisticsData.statistics.average_order_value }}
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/customers.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/customers.html.twig new file mode 100644 index 0000000000..7e8cd9cbdb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/customers.html.twig @@ -0,0 +1,26 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set statisticsData = hookable_metadata.context.statisticsData %} + +
+
+
+
+ Loading +
+
+
+
+
+ + {{ _icon({ icon: 'users' }) }} + +
+
+
{{ 'sylius.ui.customers'|trans }}
+
{{ _context.statisticsData.statistics.number_of_new_customers }}
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/paid_orders.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/paid_orders.html.twig new file mode 100644 index 0000000000..98c7742176 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/paid_orders.html.twig @@ -0,0 +1,26 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set statisticsData = hookable_metadata.context.statisticsData %} + +
+
+
+
+ Loading +
+
+
+
+
+ + {{ _icon({ icon: 'shopping-bag' }) }} + +
+
+
{{ 'sylius.ui.paid_orders'|trans }}
+
{{ _context.statisticsData.statistics.number_of_new_orders }}
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/sales.html.twig b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/sales.html.twig new file mode 100644 index 0000000000..24939c6c52 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/dashboard/index/content/statistics_grid/sales.html.twig @@ -0,0 +1,26 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set statisticsData = hookable_metadata.context.statisticsData %} + +
+
+
+
+ Loading +
+
+
+
+
+ + {{ _icon({ icon: 'coins' }) }} + +
+
+
{{ 'sylius.ui.sales'|trans }}
+
{{ _context.statisticsData.statistics.total_sales }}
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Email/layout.html.twig b/src/Sylius/Bundle/AdminBundle/templates/email/layout.html.twig similarity index 100% rename from src/Sylius/Bundle/AdminBundle/Resources/views/Email/layout.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/email/layout.html.twig diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Email/shipmentConfirmation.html.twig b/src/Sylius/Bundle/AdminBundle/templates/email/shipment_confirmation.html.twig similarity index 100% rename from src/Sylius/Bundle/AdminBundle/Resources/views/Email/shipmentConfirmation.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/email/shipment_confirmation.html.twig diff --git a/src/Sylius/Bundle/AdminBundle/templates/inventory/grid/field/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/templates/inventory/grid/field/inventory.html.twig new file mode 100644 index 0000000000..f3c030aebc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/inventory/grid/field/inventory.html.twig @@ -0,0 +1,19 @@ +{% import '@SyliusAdmin/shared/helper/icon.html.twig' as _icon %} + +{% if data.isTracked %} +
+ {{ _icon.icon({ icon: 'cube', class: 'icon icon-tabler mr-1' }) }} +
+ {{ data.onHand }} {{ 'sylius.ui.available_on_hand'|trans }} + {% if data.onHold > 0 %} +
+ {{ data.onHold }} {{ 'sylius.ui.reserved'|trans }} + {% endif %} +
+
+{% else %} + + + {{ 'sylius.ui.not_tracked'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/inventory/grid/field/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/inventory/grid/field/name.html.twig new file mode 100644 index 0000000000..c3a47295f3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/inventory/grid/field/name.html.twig @@ -0,0 +1,6 @@ +
+
+ {{ data.product.name }} +
+
{{ data.name }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/inventory/index.html.twig b/src/Sylius/Bundle/AdminBundle/templates/inventory/index.html.twig new file mode 100644 index 0000000000..caf96cb299 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/inventory/index.html.twig @@ -0,0 +1,3 @@ +{% extends '@SyliusAdmin/shared/crud/index.html.twig' %} + +{% set resource_name = 'inventory' %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/locale/grid/field/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/locale/grid/field/name.html.twig new file mode 100644 index 0000000000..f323fac9cb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/locale/grid/field/name.html.twig @@ -0,0 +1,2 @@ + +{{ data }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/cancelled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/cancelled.html.twig new file mode 100644 index 0000000000..9a1403e9e2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/cancelled.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.cancelled'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/fulfilled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/fulfilled.html.twig new file mode 100644 index 0000000000..1a252bf045 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/fulfilled.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.fulfilled'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/new.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/new.html.twig new file mode 100644 index 0000000000..ba32afc8d5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/order_state/new.html.twig @@ -0,0 +1,3 @@ + + {{ 'sylius.ui.new'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/authorized.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/authorized.html.twig new file mode 100644 index 0000000000..9e1f8cd1cd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/authorized.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.authorized'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/awaiting_payment.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/awaiting_payment.html.twig new file mode 100644 index 0000000000..eee21b37ee --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/awaiting_payment.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.awaiting_payment'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/cancelled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/cancelled.html.twig new file mode 100644 index 0000000000..b756f77fad --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/cancelled.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.cancelled'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/paid.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/paid.html.twig new file mode 100644 index 0000000000..70c06d1e04 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/paid.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.paid'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_authorized.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_authorized.html.twig new file mode 100644 index 0000000000..2058c70218 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_authorized.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.partially_authorized'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_paid.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_paid.html.twig new file mode 100644 index 0000000000..b9f0c3c88a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_paid.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.partially_paid'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_refunded.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_refunded.html.twig new file mode 100644 index 0000000000..682f6e0043 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/partially_refunded.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.partially_refunded'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/refunded.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/refunded.html.twig new file mode 100644 index 0000000000..4b02125bf1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/payment_state/refunded.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.refunded'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/cancelled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/cancelled.html.twig new file mode 100644 index 0000000000..a9419620a1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/cancelled.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.cancelled'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/partially_shipped.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/partially_shipped.html.twig new file mode 100644 index 0000000000..478cf841e3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/partially_shipped.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.partially_shipped'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/ready.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/ready.html.twig new file mode 100644 index 0000000000..182212cea8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/ready.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.ready'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/shipped.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/shipped.html.twig new file mode 100644 index 0000000000..b2561f47ee --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/common/label/shipping_state/shipped.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.shipped'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form.html.twig new file mode 100644 index 0000000000..082a449468 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form.html.twig @@ -0,0 +1,14 @@ +{# Rendered with using \Sylius\Bundle\AdminBundle\TwigComponent\Address\AddressType #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: false}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/billing_address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/billing_address.html.twig new file mode 100644 index 0000000000..28b4c94b03 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/billing_address.html.twig @@ -0,0 +1,10 @@ +
+
+ {{ 'sylius.ui.billing_address'|trans }} +
+
+
+ {% hook 'billing_address' with { form: hookable_metadata.context.form.billingAddress } %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/city.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/city.html.twig new file mode 100644 index 0000000000..97b66abfda --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/city.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.city) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/company.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/company.html.twig new file mode 100644 index 0000000000..b34c42bcd2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/company.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.company) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/country.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/country.html.twig new file mode 100644 index 0000000000..95f10508e9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/country.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.countryCode) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/first_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/first_name.html.twig new file mode 100644 index 0000000000..326159c077 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/first_name.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.firstName) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/last_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/last_name.html.twig new file mode 100644 index 0000000000..aabb34ef67 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/last_name.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.lastName) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/phone_number.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/phone_number.html.twig new file mode 100644 index 0000000000..2d69c73329 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/phone_number.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.phoneNumber) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/postcode.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/postcode.html.twig new file mode 100644 index 0000000000..289bfe22c3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/postcode.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.postcode) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/province.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/province.html.twig new file mode 100644 index 0000000000..7c0d1dc95e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/province.html.twig @@ -0,0 +1,9 @@ +
+ {% if hookable_metadata.context.form.provinceName is defined %} + {{ form_row(hookable_metadata.context.form.provinceName) }} + {% endif %} + + {% if hookable_metadata.context.form.provinceCode is defined %} + {{ form_row(hookable_metadata.context.form.provinceCode) }} + {% endif %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/common/street_address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/street_address.html.twig new file mode 100644 index 0000000000..ae162ac2eb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/common/street_address.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.street) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/form/shipping_address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/form/shipping_address.html.twig new file mode 100644 index 0000000000..16e7a5f4eb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/form/shipping_address.html.twig @@ -0,0 +1,10 @@ +
+
+ {{ 'sylius.ui.shipping_address'|trans }} +
+
+
+ {% hook 'shipping_address' with { form: hookable_metadata.context.form.shippingAddress } %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/grid/field/order_total.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/grid/field/order_total.html.twig new file mode 100644 index 0000000000..3e8581d60b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/grid/field/order_total.html.twig @@ -0,0 +1,3 @@ +{% import "@SyliusAdmin/shared/helper/money.html.twig" as _money %} + +{{ _money.format(data.total, data.currencyCode) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history.html.twig new file mode 100644 index 0000000000..73a91293f4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history.html.twig @@ -0,0 +1,9 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% block title %} + {{ 'sylius.ui.history'|trans }} | {{ parent() }} +{% endblock %} + +{% block body %} + {% hook 'sylius_admin.order.history' with { resource, metadata, configuration } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..b3e41d4f0e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/breadcrumbs.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as breadcrumbs %} + +{% set order = hookable_metadata.context.resource %} + +{{ breadcrumbs.default([ + { name: 'sylius.ui.dashboard'|trans, url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.orders'|trans, url: path('sylius_admin_order_index'), active: false }, + { name: '#' ~ order.number, url: path('sylius_admin_order_show', {'id': order.id}), active: false }, + { name: 'sylius.ui.history'|trans, active: true } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..5460d82cc0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/actions.html.twig @@ -0,0 +1,12 @@ +{% set resource = hookable_metadata.context.resource %} + +
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/actions/back.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/actions/back.html.twig new file mode 100644 index 0000000000..e464f7c06c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/actions/back.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set resource = hookable_metadata.context.resource %} + + + {{ icon({ icon: 'arrow-back-up', class: 'icon dropdown-item-icon icon-tabler' }) }} + {{ 'sylius.ui.back'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..0352b61145 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/header/title_block/title.html.twig @@ -0,0 +1,13 @@ +{% from '@SyliusAdmin/order/macro/order_state_label.html.twig' import label %} + +{% set order = hookable_metadata.context.resource %} + +
+
+

+ {{ 'sylius.ui.order'|trans }} + #{{ order.number }} +

+ {{ label(order.state) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections.html.twig new file mode 100644 index 0000000000..a06fc6d4e8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections.html.twig @@ -0,0 +1,9 @@ +
+
+
+
+ {% hook 'sections' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections/addresses.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections/addresses.html.twig new file mode 100644 index 0000000000..776d3d7c99 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections/addresses.html.twig @@ -0,0 +1,12 @@ +
+
+
{{ 'sylius.ui.addresses'|trans }}
+
+
+
+
+ {% hook 'addresses' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections/addresses/address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections/addresses/address.html.twig new file mode 100644 index 0000000000..064a82e788 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/content/sections/addresses/address.html.twig @@ -0,0 +1,47 @@ +{% from '@SyliusAdmin/order/history/macro/action_label.html.twig' import label %} + +{% set header = (header|default('sylius.ui.address'))|trans %} + +
+
+
+
{{ header }}
+
+
+ + + + + + + + + + {%- for log in addressLogs -%} + + + + + + {%- endfor -%} + +
{{ 'sylius.ui.actions'|trans }}{{ 'sylius.ui.logged_at'|trans }}{{ 'sylius.ui.changes'|trans }}
{{ label(log) }} + {{ log.loggedAt|date('Y-m-d') }}
+ {{ log.loggedAt|date('H:i:s') }} +
+
+ + + {%- for field, data in log.data|filter(data => not data is empty) -%} + + + + + {%- endfor -%} + +
{{ ('sylius.ui.' ~ field|u.snake)|trans }}{{ data }}
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/history/macro/action_label.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/history/macro/action_label.html.twig new file mode 100644 index 0000000000..624db438e7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/history/macro/action_label.html.twig @@ -0,0 +1,25 @@ +{%- macro label(log) -%} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + + {% if log.action == 'create' %} +
+ {{ icon({icon: 'plus'}) }} +
+ {{ 'sylius.ui.created'|trans }} +
+
+ {% elseif log.action == 'update' %} +
+ {{ icon({icon: 'pencil'}) }} +
+ {{ 'sylius.ui.updated'|trans }} +
+
+ {% else %} +
+
+ {{ log.action|title }} +
+
+ {% endif %} +{%- endmacro -%} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/macro/order_state_label.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/macro/order_state_label.html.twig new file mode 100644 index 0000000000..b23f1101a3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/macro/order_state_label.html.twig @@ -0,0 +1,19 @@ +{%- macro label(state) -%} + {% if state == constant('Sylius\\Component\\Order\\Model\\OrderInterface::STATE_NEW') %} + + {{ 'sylius.ui.new'|trans }} + + {% elseif state == constant('Sylius\\Component\\Order\\Model\\OrderInterface::STATE_FULFILLED') %} + + {{ 'sylius.ui.fulfilled'|trans }} + + {% elseif state == constant('Sylius\\Component\\Order\\Model\\OrderInterface::STATE_CANCELLED') %} + + {{ 'sylius.ui.cancelled'|trans }} + + {% else %} + + {{ state|title }} + + {% endif %} +{%- endmacro -%} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..cd0e9fec20 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/breadcrumbs.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as breadcrumbs %} + +{% set order = hookable_metadata.context.resource %} + +{{ breadcrumbs.default([ + { name: 'sylius.ui.dashboard'|trans, url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.orders'|trans, url: path('sylius_admin_order_index'), active: false }, + { name: '#' ~ order.number, active: true }, + { name: 'sylius.ui.show'|trans, active: false } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..2a34e4c332 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions.html.twig @@ -0,0 +1,12 @@ +{% set resource = hookable_metadata.context.resource %} + +
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/cancel.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/cancel.html.twig new file mode 100644 index 0000000000..aef17c61cb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/cancel.html.twig @@ -0,0 +1,14 @@ +{% set order = hookable_metadata.context.resource %} + +{% if sylius_sm_can(order, constant('Sylius\\Component\\Order\\OrderTransitions::GRAPH'), constant('Sylius\\Component\\Order\\OrderTransitions::TRANSITION_CANCEL')) %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as icon %} + +
+ + + +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/history.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/history.html.twig new file mode 100644 index 0000000000..ab7ce0a813 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/history.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set resource = hookable_metadata.context.resource %} + + + {{ icon({ icon: 'history', class: 'icon dropdown-item-icon icon-tabler' }) }} + {{ 'sylius.ui.history'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/resend_confirmation_email.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/resend_confirmation_email.html.twig new file mode 100644 index 0000000000..3b300beb3c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/actions/resend_confirmation_email.html.twig @@ -0,0 +1,11 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set order = hookable_metadata.context.resource %} + +{% if order.state in sylius_order_states_that_allows_to_resend_order_confirmation_email %} + {% set path = path('sylius_admin_order_resend_confirmation_email', {'id': order.id, '_csrf_token': csrf_token(order.id)}) %} + + {{ icon({ icon: 'send', class: 'icon dropdown-item-icon icon-tabler' }) }} + {{ 'sylius.ui.resend_the_order_confirmation_email'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..0352b61145 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/header/title_block/title.html.twig @@ -0,0 +1,13 @@ +{% from '@SyliusAdmin/order/macro/order_state_label.html.twig' import label %} + +{% set order = hookable_metadata.context.resource %} + +
+
+

+ {{ 'sylius.ui.order'|trans }} + #{{ order.number }} +

+ {{ label(order.state) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections.html.twig new file mode 100644 index 0000000000..4f67440f67 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections.html.twig @@ -0,0 +1,12 @@ +
+
+
+
+ {% hook 'sections#right' %} +
+
+ {% hook 'sections#left' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer.html.twig new file mode 100644 index 0000000000..085461c2dd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer.html.twig @@ -0,0 +1,12 @@ +
+
+
+ {{ (_context.title|default('sylius.ui.customer'))|trans }} +
+
+
+
+ {% hook 'customer' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/billing_address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/billing_address.html.twig new file mode 100644 index 0000000000..c48789cb25 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/billing_address.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/shared/helper/address.html.twig' as _address %} + +{% set order = hookable_metadata.context.resource %} + +
+ {{ 'sylius.ui.billing_address'|trans }} +
+
+ {{ _address.default(order.billingAddress) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/customer_since.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/customer_since.html.twig new file mode 100644 index 0000000000..fdc382fdbd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/customer_since.html.twig @@ -0,0 +1,6 @@ +{% set customer = hookable_metadata.context.resource.customer %} + +
+ {{ 'sylius.ui.customer_since'|trans }}: +
+
{{ customer.createdAt|format_date }}
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/edit_addresses.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/edit_addresses.html.twig new file mode 100644 index 0000000000..5932757aea --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/edit_addresses.html.twig @@ -0,0 +1,7 @@ +{% set order = hookable_metadata.context.resource %} + + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/email.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/email.html.twig new file mode 100644 index 0000000000..581465f1be --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/email.html.twig @@ -0,0 +1,8 @@ +{% set customer = hookable_metadata.context.resource.customer %} + +
+ {{ 'sylius.ui.email'|trans }}: +
+ diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/full_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/full_name.html.twig new file mode 100644 index 0000000000..cd7e0a7147 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/full_name.html.twig @@ -0,0 +1,10 @@ +{% set customer = hookable_metadata.context.resource.customer %} + +
+ {{ 'sylius.ui.name'|trans }}: +
+ diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/phone.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/phone.html.twig new file mode 100644 index 0000000000..e88766efdd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/phone.html.twig @@ -0,0 +1,14 @@ +{% set customer = hookable_metadata.context.resource.customer %} + +
+ {{ 'sylius.ui.phone_number'|trans }}: +
+
+ + {% if customer.phoneNumber is not null or customer.phoneNumber is not empty %} + {{ customer.phoneNumber }} + {% else %} + - + {% endif %} + +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/shipping_address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/shipping_address.html.twig new file mode 100644 index 0000000000..784e735357 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/customer/shipping_address.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/shared/helper/address.html.twig' as _address %} + +{% set order = hookable_metadata.context.resource %} + +
+ {{ 'sylius.ui.shipping_address'|trans }} +
+
+ {{ _address.default(_context.order.shippingAddress) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details.html.twig new file mode 100644 index 0000000000..3c33936bf3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details.html.twig @@ -0,0 +1,12 @@ +
+
+
+ {{ (_context.title|default('sylius.ui.details'))|trans }} +
+
+
+
+ {% hook 'details' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/channel.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/channel.html.twig new file mode 100644 index 0000000000..6e85c52eba --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/channel.html.twig @@ -0,0 +1,11 @@ +{% set order = hookable_metadata.context.resource %} + +
+
+ {{ 'sylius.ui.channel'|trans }}: +
+
+ + {{ order.channel.name }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/currency.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/currency.html.twig new file mode 100644 index 0000000000..8faf3ece69 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/currency.html.twig @@ -0,0 +1,8 @@ +{% set order = hookable_metadata.context.resource %} + +
+
+ {{ 'sylius.ui.currency'|trans }}: +
+
{{ order.currencyCode }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/language.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/language.html.twig new file mode 100644 index 0000000000..f6a8a20000 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/language.html.twig @@ -0,0 +1,10 @@ +{% set order = hookable_metadata.context.resource %} + +
+
+ {{ 'sylius.ui.language'|trans }}: +
+
+ {{ order.localeCode|sylius_locale_name }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/order_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/order_date.html.twig new file mode 100644 index 0000000000..e044b8546b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/details/order_date.html.twig @@ -0,0 +1,10 @@ +{% set order = hookable_metadata.context.resource %} + +
+
+ {{ 'sylius.ui.order.date'|trans }}: +
+
+ {{ order.checkoutCompletedAt|format_datetime }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/items.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/items.html.twig new file mode 100644 index 0000000000..014baa5451 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/items.html.twig @@ -0,0 +1,99 @@ +{% import '@SyliusAdmin/shared/helper/product.html.twig' as _product %} +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} +{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} +{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} + +{% set order = hookable_metadata.context.resource %} + +
+
+
{{ 'sylius.ui.items'|trans }}
+
+
+ + + + + + + + + + + + + + + + {% for item in order.items %} + {% set variant = item.variant %} + {% set product = variant.product %} + + {% set aggregatedUnitPromotionAdjustments = item.getAdjustmentsTotalRecursively(unitPromotionAdjustment) + item.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} + {% set subtotal = (item.unitPrice * item.quantity) + aggregatedUnitPromotionAdjustments %} + + {% set taxIncluded = sylius_admin_order_unit_tax_included(item) %} + {% set taxExcluded = sylius_admin_order_unit_tax_excluded(item) %} + + + + + + + + + + + + + {% endfor %} + + + + + + + + +
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.unit_price'|trans|replace({ " ": "
" })|raw }}
{{ 'sylius.ui.unit_discount'|trans|replace({ " ": "
" })|raw }}
{{ 'sylius.ui.distributed_order_discount'|trans|replace({ " ": "
" })|raw }}
{{ 'sylius.ui.discounted_unit_price'|trans|replace({ " ": "
" })|raw }}
{{ 'sylius.ui.quantity'|trans }}{{ 'sylius.ui.subtotal'|trans }}{{ 'sylius.ui.tax'|trans }}{{ 'sylius.ui.total'|trans }}
+
+
+ {{ _product.image(product) }} +
+
+ +
{{ variant.code }}
+
{{ variant.name }}
+
+
+
+ {{ _money.format(item.unitPrice, order.currencyCode) }} + + {{ _money.format(item.units.first.adjustmentsTotal(unitPromotionAdjustment), order.currencyCode) }} + + ~ {{ _money.format(item.units.first.adjustmentsTotal(orderPromotionAdjustment), order.currencyCode) }} + + {{ _money.format(item.fullDiscountedUnitPrice, order.currencyCode) }} + + {{ item.quantity }} + + {{ _money.format(subtotal, order.currencyCode) }} + +
{{ _money.format(taxExcluded, order.currencyCode) }}
+
+
{{ _money.format(taxIncluded, order.currencyCode) }} +
+ ({{ 'sylius.ui.included_in_price'|trans }}) +
+
+ {{ _money.format(item.total, order.currencyCode) }} +
{{ 'sylius.ui.total'|trans }}{{ _money.format(order.taxTotal, order.currencyCode) }}{{ _money.format(order.itemsTotal, order.currencyCode) }}
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments.html.twig new file mode 100644 index 0000000000..79ed322527 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set order = hookable_metadata.context.resource %} + +
+ {% hook 'payments' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header.html.twig new file mode 100644 index 0000000000..623fb6ce0e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'header' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header/state.html.twig new file mode 100644 index 0000000000..1ecc1b93cb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header/state.html.twig @@ -0,0 +1,5 @@ +{% set order = hookable_metadata.context.resource %} + + + {{ include('@SyliusAdmin/order/common/label/payment_state/' ~ order.paymentState ~ '.html.twig') }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header/title.html.twig new file mode 100644 index 0000000000..7347a6e75d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/header/title.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.payments'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions.html.twig new file mode 100644 index 0000000000..adda10e322 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions.html.twig @@ -0,0 +1,5 @@ + +
+ {% hook 'actions' %} +
+ diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions/complete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions/complete.html.twig new file mode 100644 index 0000000000..d263503ae2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions/complete.html.twig @@ -0,0 +1,14 @@ +{% set order = hookable_metadata.context.resource %} +{% set payment = hookable_metadata.context.payment %} + +{% if sylius_sm_can(payment, constant('Sylius\\Component\\Payment\\PaymentTransitions::GRAPH'), constant('Sylius\\Component\\Payment\\PaymentTransitions::TRANSITION_COMPLETE')) %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as icon %} + +
+ + + +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions/refund.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions/refund.html.twig new file mode 100644 index 0000000000..dc716c5ab1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/actions/refund.html.twig @@ -0,0 +1,14 @@ +{% set order = hookable_metadata.context.resource %} +{% set payment = hookable_metadata.context.payment %} + +{% if sylius_sm_can(payment, constant('Sylius\\Component\\Payment\\PaymentTransitions::GRAPH'), constant('Sylius\\Component\\Payment\\PaymentTransitions::TRANSITION_REFUND')) %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as icon %} + +
+ + + +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/amount.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/amount.html.twig new file mode 100644 index 0000000000..92854f07da --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/amount.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as money %} + +{% set payment = hookable_metadata.context.payment %} + + + {{ money.format(payment.amount, payment.currencyCode) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/name.html.twig new file mode 100644 index 0000000000..b45a2864d0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/name.html.twig @@ -0,0 +1,5 @@ +{% set payment = hookable_metadata.context.payment %} + + + {{ payment.method.name }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/state.html.twig new file mode 100644 index 0000000000..d44d93b78a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/item/state.html.twig @@ -0,0 +1,5 @@ +{% set payment = hookable_metadata.context.payment %} + + +
{{ ('sylius.ui.' ~ payment.state)|trans|upper }}
+ diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/items.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/items.html.twig new file mode 100644 index 0000000000..ac53b11cc6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/payments/items.html.twig @@ -0,0 +1,17 @@ +{% set order = hookable_metadata.context.resource %} + +
+ {% if order.hasPayments %} + + + + {% for payment in order.payments %} + {% hook 'item' with { resource: order, payment } %} + {% endfor %} + + +
+ {% else %} + {{ 'sylius.ui.no_payments'|trans }} + {% endif %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments.html.twig new file mode 100644 index 0000000000..c936d77991 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'shipments' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header.html.twig new file mode 100644 index 0000000000..623fb6ce0e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'header' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header/state.html.twig new file mode 100644 index 0000000000..bbe4d82ce1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header/state.html.twig @@ -0,0 +1,5 @@ +{% set order = hookable_metadata.context.resource %} + + + {{ include('@SyliusAdmin/order/common/label/shipping_state/' ~ order.shippingState ~ '.html.twig') }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header/title.html.twig new file mode 100644 index 0000000000..b685ea7499 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/header/title.html.twig @@ -0,0 +1 @@ +{{ 'sylius.ui.shipments'|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions.html.twig new file mode 100644 index 0000000000..adda10e322 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions.html.twig @@ -0,0 +1,5 @@ + +
+ {% hook 'actions' %} +
+ diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions/resend_confirmation.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions/resend_confirmation.html.twig new file mode 100644 index 0000000000..552b94d9df --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions/resend_confirmation.html.twig @@ -0,0 +1,8 @@ +{% set shipment = hookable_metadata.context.shipment %} + +{% if shipment.state == 'shipped' %} + {% set resendPath = path('sylius_admin_shipment_resend_confirmation_email', {'id': shipment.id, '_csrf_token': csrf_token(shipment.id)}) %} + + {{ 'sylius.ui.resend_the_shipment_confirmation_email'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions/show.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions/show.html.twig new file mode 100644 index 0000000000..e9b5970fad --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/actions/show.html.twig @@ -0,0 +1,7 @@ +{% set shipment = hookable_metadata.context.shipment %} + +{% if shipment.state != 'cart' %} + + {{ 'sylius.ui.show'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/details.html.twig new file mode 100644 index 0000000000..173973faa0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/details.html.twig @@ -0,0 +1,22 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set shipment = hookable_metadata.context.shipment %} + + +
+ {{ shipment.method.name }} +
{{ _icon({ icon: 'world' }) }} {{ shipment.method.zone }}
+
+ {% if shipment.shippedAt is not empty %} +
+ {{ 'sylius.ui.shipped_at'|trans }}: + {{ shipment.shippedAt|date('d-m-Y H:i') }} +
+ {% endif %} + {% if shipment.state == 'shipped' and shipment.tracking is not empty %} +
+ {{ 'sylius.ui.tracking_code'|trans }}: + {{ shipment.tracking }} +
+ {% endif %} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/state.html.twig new file mode 100644 index 0000000000..11000ceb80 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/item/state.html.twig @@ -0,0 +1,5 @@ +{% set shipment = hookable_metadata.context.shipment %} + + +
{{ ('sylius.ui.' ~ shipment.state)|trans|upper }}
+ diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/items.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/items.html.twig new file mode 100644 index 0000000000..5bada2d8ed --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/shipments/items.html.twig @@ -0,0 +1,17 @@ +{% set order = hookable_metadata.context.resource %} + +
+ {% if order.hasShipments %} + + + + {% for shipment in order.shipments %} + {% hook 'item' with { shipment } %} + {% endfor %} + + +
+ {% else %} + {{ 'sylius.ui.there_are_no_shipments_to_display'|trans }} + {% endif %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary.html.twig new file mode 100644 index 0000000000..29819dc936 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary.html.twig @@ -0,0 +1,28 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set order = hookable_metadata.context.resource %} + +
+
+
{{ (_context.title|default('sylius.ui.summary'))|trans }}
+
+
+ {% block content %} + + {% block table %} + + {% hook 'summary' %} + + {% endblock %} +
+ {% endblock %} +
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/items_total.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/items_total.html.twig new file mode 100644 index 0000000000..da61015593 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/items_total.html.twig @@ -0,0 +1,8 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set order = hookable_metadata.context.resource %} + + + {{ 'sylius.ui.items_total'|trans }}: + {{ _money.format(order.itemsTotal, order.currencyCode) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/promotion_total.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/promotion_total.html.twig new file mode 100644 index 0000000000..5ecd1a5f91 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/promotion_total.html.twig @@ -0,0 +1,26 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set order = hookable_metadata.context.resource %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} + +{% set orderPromotionAdjustments = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderPromotionAdjustment)) %} +{% set unitPromotionAdjustments = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(unitPromotionAdjustment)) %} +{% set promotionAdjustments = orderPromotionAdjustments|merge(unitPromotionAdjustments) %} +{% set totalAdjustments = promotionAdjustments|reduce((carry, v) => carry + v) %} + + + +
+
{{ 'sylius.ui.promotion_total'|trans }}:
+
+ + + {% if totalAdjustments == 0 %} +

{{ 'sylius.ui.no_promotion'|trans }}

+ {% else %} + {{ _money.format(totalAdjustments, order.currencyCode) }} + {% endif %} + + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/shipping_total.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/shipping_total.html.twig new file mode 100644 index 0000000000..1a1c53812a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/shipping_total.html.twig @@ -0,0 +1,17 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set order = hookable_metadata.context.resource %} + + + +
+
{{ 'sylius.ui.shipping_total'|trans }}:
+
+
+ {{ order.adjustments('shipping')|map(s => "#{s.label}: #{_money.format(s.amount, order.currencyCode)}")|join(", ") }} +
+
+
+ + {{ _money.format(order.shippingTotal, order.currencyCode) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/tax_total.html.twig b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/tax_total.html.twig new file mode 100644 index 0000000000..ca0880fda1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/order/show/content/sections/summary/tax_total.html.twig @@ -0,0 +1,8 @@ +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set order = hookable_metadata.context.resource %} + + + {{ 'sylius.ui.tax_total'|trans }}: + {{ _money.format(order.taxTotal, order.currencyCode) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form.html.twig new file mode 100644 index 0000000000..ad4d55ed7c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form.html.twig @@ -0,0 +1,18 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\PaymentMethod\FormComponent #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{% set configuration = hookable_metadata.configuration %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: false}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections.html.twig new file mode 100644 index 0000000000..86a74da537 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections.html.twig @@ -0,0 +1 @@ +{% hook 'sections' %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration.html.twig new file mode 100644 index 0000000000..8049356ccc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration.html.twig @@ -0,0 +1,14 @@ +{% set gateway_type = hookable_metadata.context.form.vars.data.gatewayConfig.factoryName %} + +
+
+
{{ 'sylius.ui.gateway_configuration'|trans }}
+
+ +
+
+ {% hook 'gateway_configuration' %} + {% hook 'gateway_configuration' ~ '.' ~ gateway_type %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/password.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/password.html.twig new file mode 100644 index 0000000000..ce7af67962 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/password.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.config.password, sylius_test_form_attribute('password')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/sandbox.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/sandbox.html.twig new file mode 100644 index 0000000000..5f3c24571a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/sandbox.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.config.sandbox, sylius_test_form_attribute('sandbox')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/signature.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/signature.html.twig new file mode 100644 index 0000000000..dcd0cabe45 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/signature.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.config.signature, sylius_test_form_attribute('signature')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/username.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/username.html.twig new file mode 100644 index 0000000000..492b0e59fe --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/paypal/username.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.config.username, sylius_test_form_attribute('username')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/stripe/publishable_key.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/stripe/publishable_key.html.twig new file mode 100644 index 0000000000..632644cc32 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/stripe/publishable_key.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.config.publishable_key, sylius_test_form_attribute('publishable-key')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/stripe/secret_key.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/stripe/secret_key.html.twig new file mode 100644 index 0000000000..9486eecb07 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/stripe/secret_key.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.config.secret_key, sylius_test_form_attribute('secret-key')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/type.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/type.html.twig new file mode 100644 index 0000000000..232e5c9b57 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/gateway_configuration/type.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.gatewayConfig.factoryName, sylius_test_form_attribute('factory-name')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general.html.twig new file mode 100644 index 0000000000..d071e7f60d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general.html.twig @@ -0,0 +1,11 @@ +
+
+
{{ 'sylius.ui.general'|trans }}
+
+ +
+
+ {% hook 'general' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/channels.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/channels.html.twig new file mode 100644 index 0000000000..2064ae1c5e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/channels.html.twig @@ -0,0 +1,9 @@ +{% set channels = hookable_metadata.context.form.channels %} + +
+ {{ form_label(channels) }} + + {% for channel in channels %} + {{ form_row(channel, sylius_test_form_attribute('channel-name', channel.vars.label)|merge({ label_attr: { class: 'checkbox-switch' } })) }} + {% endfor %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/code.html.twig new file mode 100644 index 0000000000..a83d5a18c3 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/code.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.code, sylius_test_form_attribute('code')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/enabled.html.twig new file mode 100644 index 0000000000..5c1d4cc2f7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/enabled.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.enabled, sylius_test_form_attribute('enabled')|merge({ label_attr: { class: 'checkbox-switch' } })) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/position.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/position.html.twig new file mode 100644 index 0000000000..d61dfd1b0a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/general/position.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.position, sylius_test_form_attribute('position')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations.html.twig new file mode 100644 index 0000000000..c8be4f2f71 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations.html.twig @@ -0,0 +1,16 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +{% set form = hookable_metadata.context.form %} +{% set prefixes = hookable_metadata.prefixes %} + +
+
+
{{ 'sylius.ui.translations'|trans }}
+
+ +
+
+ {{ _translations.with_hook(form.translations, prefixes) }} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/description.html.twig new file mode 100644 index 0000000000..1f980759cf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/description.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.description, sylius_test_form_attribute('description')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/instructions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/instructions.html.twig new file mode 100644 index 0000000000..ff8c17b26e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/instructions.html.twig @@ -0,0 +1,12 @@ +{% set form = hookable_metadata.context.form %} +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
+
+
+
{{ _icon({ 'icon': 'info-circle', 'class': 'alert-icon' }) }}
+
{{ 'sylius.ui.the_instructions_below_will_be_displayed_to_the_customer'|trans }}
+
+
+ {{ form_row(form.instructions, sylius_test_form_attribute('instructions')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/name.html.twig new file mode 100644 index 0000000000..96597c2165 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/form/sections/translations/name.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form %} + +
+ {{ form_row(form.name, sylius_test_form_attribute('name')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/payment_method/grid/action/create.html.twig b/src/Sylius/Bundle/AdminBundle/templates/payment_method/grid/action/create.html.twig new file mode 100644 index 0000000000..b2c2df596f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/payment_method/grid/action/create.html.twig @@ -0,0 +1,12 @@ +{% import '@SyliusAdmin/shared/helper/dropdown.html.twig' as _dropdown %} + +{{ _dropdown.list( + { + direction: 'down-end', + button: { text: 'sylius.ui.create'|trans, icon: 'plus' } + }, + sylius_admin_get_payment_gateways()|map((gatewayName, gatewayServiceId) => { + title: gatewayName|trans, + url: path('sylius_admin_payment_method_create', { 'factory': gatewayServiceId }), + }) +) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/common/header/title_block/actions/view_in_store.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/common/header/title_block/actions/view_in_store.html.twig new file mode 100644 index 0000000000..cb350e22cf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/common/header/title_block/actions/view_in_store.html.twig @@ -0,0 +1,50 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% set product = (hookable_metadata.context.resource) %} +{% set enabled_channels = product.channels|filter(channel => channel.enabled == true) %} + +{% if sylius_bundle_loaded_checker('SyliusShopBundle') %} + {% if not product.enabled or enabled_channels|length < 1 %} + + {{ _icon({ icon: 'arrow-up-right', class: 'icon icon-tabler' }) }} + {{ 'sylius.ui.view_in_store'|trans }} + + {% elseif enabled_channels|length > 1 %} + + {% else %} + {% for channel in enabled_channels %} + {% set product_translation = sylius_product_translation(product, channel) %} + {% if product_translation is not null %} + {% set url = sylius_channel_url(path('sylius_shop_product_show', {'slug': product_translation.slug, '_locale': product_translation.locale}), channel) %} + {% endif %} + + + {{ _icon({ icon: 'arrow-up-right', class: 'icon icon-tabler' }) }} + {{ 'sylius.ui.view_in_store'|trans }} + + {% endfor %} + {% endif %} +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form.html.twig new file mode 100644 index 0000000000..58d07b1240 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form.html.twig @@ -0,0 +1,22 @@ +{# Rendered with using \Sylius\Bundle\AdminBundle\TwigComponent\Product\FormComponent #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} +
+ {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { + mappedProductAttributes, + attributesToBeAdded, + resource, + form, + } %} +
+ {{ form_end(form, {render_rest: hookable.configuration.render_rest|default(false)}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections.html.twig new file mode 100644 index 0000000000..b01a02870e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'sections' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/associations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/associations.html.twig new file mode 100644 index 0000000000..ec21bed242 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/associations.html.twig @@ -0,0 +1,14 @@ +
+
+
+

+ {{ 'sylius.ui.associations'|trans }} +

+
+
+
+ {{ form_row(hookable_metadata.context.form.associations) }} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/attributes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/attributes.html.twig new file mode 100644 index 0000000000..c86846404b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/attributes.html.twig @@ -0,0 +1,110 @@ +{% set productAttributes = hookable_metadata.context.mappedProductAttributes %} +{% set attributesToBeAdded = hookable_metadata.context.attributesToBeAdded %} + +
+
+
+

+ {{ 'sylius.ui.attributes'|trans }} {{ 'sylius.ui.work_in_progress'|trans }} +

+
+
+
+ + +
+
+
+
+
+
+ {% for productAttributeCode, productAttributeValue in productAttributes %} + {% set productAttributeName = (productAttributeValue|first).vars.data.name %} + + {% endfor %} +
+
+
+
+
+
+ {% for productAttributeCode, productAttributeValues in productAttributes %} +
+ {% for productAttributeValue in productAttributeValues %} + {% set localeCode = productAttributeValue.vars.data.localeCode %} +
+
+ {% if localeCode is not null %} + + {% else %} + + {% endif %} +
+
+
+ {{ form_label(productAttributeValue.value) }} + {% if localeCode is not null %} + + {% endif %} +
+ {{ form_widget( + productAttributeValue.value, + sylius_test_form_attributes({ + 'attribute-value': '', + 'attribute-name': productAttributeValue.value.vars.label, + 'locale-code': productAttributeValue.localeCode.vars.value, + }) + ) }} + + + +
+
+ {% endfor %} +
+ {% endfor %} +
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/channel_pricing.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/channel_pricing.html.twig new file mode 100644 index 0000000000..a59d09d3dc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/channel_pricing.html.twig @@ -0,0 +1,62 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} +
+ {% set variantForm = hookable_metadata.context.form.variant %} + + {% set isChannelPricingInvalid = variantForm.channelPricings.vars.errors is not empty %} + + {% if isChannelPricingInvalid %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + + + {% endif %} + +
+ {% if isChannelPricingInvalid %} +
+ {% endif %} +
+ +
+
+
+ {% for channelCode, channelPricing in variantForm.channelPricings %} +
+ {% if channelCode not in product.channels|map(channel => channel.code) %} +
+ {{ 'sylius.ui.product.product_not_active_in_channel'|trans }} +
+ {% endif %} + {{ form_row(channelPricing, {'label': false}) }} +
+ {% endfor %} +
+
+
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/details.html.twig new file mode 100644 index 0000000000..1dabe4847a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/details.html.twig @@ -0,0 +1,39 @@ +{% set form = hookable_metadata.context.form %} +{% set product = form.vars.data %} + +
+
+
+

+ {{ 'sylius.ui.details'|trans }} +

+
+
+
+ {{ form_row(form.code) }} +
+
+ {{ form_row(form.enabled) }} +
+ {% if product.isSimple %} +
+ {{ form_row(form.variant.shippingRequired) }} +
+
+ {{ form_row(form.variant.translations) }} +
+ {% endif %} +
+ {{ form_row(form.channels) }} +
+ {% if product.isSimple == false %} +
+ {{ form_row(form.options, {'search_url': path('sylius_admin_ajax_product_options_by_phrase'), 'init_load_url': path('sylius_admin_ajax_find_product_options')}) }} +
+ {% endif %} +
+ {{ form_row(form.variantSelectionMethod) }} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/inventory.html.twig new file mode 100644 index 0000000000..6ca589154a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/inventory.html.twig @@ -0,0 +1,17 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + {% set variantForm = hookable_metadata.context.form.variant %} +
+
+
+

{{ 'sylius.ui.inventory'|trans }}

+
+
+ {{ form_row(variantForm.onHand) }} + {{ form_row(variantForm.tracked) }} + {{ form_row(variantForm.version) }} +
+
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/media.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/media.html.twig new file mode 100644 index 0000000000..6ea55ca67f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/media.html.twig @@ -0,0 +1,67 @@ +{% set form = hookable_metadata.context.form %} +{% set product = hookable_metadata.context.resource %} + +
+
+
+

+ {{ 'sylius.ui.media'|trans }} +

+
+
+
+ {% for imageForm in form.images %} +
+
+
+ {% if imageForm.vars.value.path is not null %} + + {% else %} + + {% endif %} +
+
+ {{ form_widget( + imageForm.vars.button_delete, + { + label: 'sylius.ui.delete'|trans, + attr: { + class: 'btn btn-outline-danger w-100', + 'data-test-image-delete': '', + } + } + ) }} +
+
+
+
+ {{ form_row(imageForm.type, sylius_test_form_attribute('type')) }} +
+
+ {% if product.id is not null and 0 != product.variants|length and not product.simple %} + {{ form_row(imageForm.productVariants, sylius_test_form_attribute('product-variant', imageForm.productVariants.vars.value|join(','))) }} + {% endif %} +
+
+ {{ form_row(imageForm.file, sylius_test_form_attribute('file')) }} +
+
+
+ {% endfor %} +
+ +
+ {{ form_widget(form.images.vars.button_add, {label: 'sylius.ui.add_image'|trans, attr: {class: 'btn btn-outline-primary '}}) }} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/shipping.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/shipping.html.twig new file mode 100644 index 0000000000..74d45ad524 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/shipping.html.twig @@ -0,0 +1,29 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + {% set variantForm = hookable_metadata.context.form.variant %} +
+
+
+

{{ 'sylius.ui.shipping'|trans }}

+
+
+
+ {{ form_row(variantForm.shippingCategory) }} +
+
+ {{ form_row(variantForm.width) }} +
+
+ {{ form_row(variantForm.height) }} +
+
+ {{ form_row(variantForm.depth) }} +
+
+ {{ form_row(variantForm.weight) }} +
+
+
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/taxes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/taxes.html.twig new file mode 100644 index 0000000000..f229c9711d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/taxes.html.twig @@ -0,0 +1,17 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + {% set variantForm = hookable_metadata.context.form.variant %} +
+
+
+

{{ 'sylius.ui.taxes'|trans }}

+
+
+
+ {{ form_row(variantForm.taxCategory) }} +
+
+
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/taxonomy.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/taxonomy.html.twig new file mode 100644 index 0000000000..86fe8a5fbb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/taxonomy.html.twig @@ -0,0 +1,11 @@ +
+
+
+

{{ 'sylius.ui.taxonomy'|trans }}

+
+
+ {{ form_row(hookable_metadata.context.form.mainTaxon, { 'search_url': path('sylius_admin_ajax_taxon_by_name_phrase'), 'init_load_url': path('sylius_admin_ajax_taxon_by_code') }) }} +
+
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/translations.html.twig new file mode 100644 index 0000000000..95c0c43cc0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/sections/translations.html.twig @@ -0,0 +1,44 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +
+
+ {% set body %} + {% verbatim %} +
+
+ {{ form_row(translationForm.name) }} +
+
+ {{ form_label(translationForm.slug) }} +
+ {{ form_widget(translationForm.slug) }} + +
+
+
+ {{ form_row(translationForm.description) }} +
+
+ {{ form_row(translationForm.metaKeywords) }} +
+
+ {{ form_row(translationForm.metaDescription) }} +
+
+ {{ form_row(translationForm.shortDescription) }} +
+
+ {% endverbatim %} + {% endset %} + {{ _translations.default(hookable_metadata.context.form.translations, body, {accordionId: 'product-translations'}) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation.html.twig new file mode 100644 index 0000000000..560cf9f794 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation.html.twig @@ -0,0 +1,7 @@ +
+
+
+ {% hook 'side_navigation' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/associations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/associations.html.twig new file mode 100644 index 0000000000..947c88ec37 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/associations.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/attributes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/attributes.html.twig new file mode 100644 index 0000000000..83df7a18cc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/attributes.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/channel_pricing.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/channel_pricing.html.twig new file mode 100644 index 0000000000..48506a3c8f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/channel_pricing.html.twig @@ -0,0 +1,14 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/details.html.twig new file mode 100644 index 0000000000..c3e7155cde --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/details.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/inventory.html.twig new file mode 100644 index 0000000000..e56c303d95 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/inventory.html.twig @@ -0,0 +1,14 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/media.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/media.html.twig new file mode 100644 index 0000000000..7a2c0b6b3a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/media.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/shipping.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/shipping.html.twig new file mode 100644 index 0000000000..32e77ed692 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/shipping.html.twig @@ -0,0 +1,14 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/taxes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/taxes.html.twig new file mode 100644 index 0000000000..309bf80729 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/taxes.html.twig @@ -0,0 +1,14 @@ +{% set product = hookable_metadata.context.resource %} + +{% if product.isSimple %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/taxonomy.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/taxonomy.html.twig new file mode 100644 index 0000000000..69b4d0cb4b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/taxonomy.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/translations.html.twig new file mode 100644 index 0000000000..4729b5e5d5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/form/side_navigation/translations.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants.html.twig new file mode 100644 index 0000000000..d390113d19 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants.html.twig @@ -0,0 +1,9 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% block title %} + {{ 'sylius.ui.generate_variants'|trans }} {{ parent() }} +{% endblock %} + +{% block body %} + {% hook 'sylius_admin.product.generate_variants' with { resource, metadata, configuration, form } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form.html.twig new file mode 100644 index 0000000000..e4e7394b2a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form.html.twig @@ -0,0 +1,16 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\Product\GenerateProductVariantsFormComponent #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: hookable.configuration.render_rest|default(false)}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants.html.twig new file mode 100644 index 0000000000..d8206dd141 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants.html.twig @@ -0,0 +1,12 @@ +{% set form = hookable_metadata.context.form %} + +
+
+

{{ 'sylius.ui.variants'|trans }}

+
+
+ {% for variant in form.variants %} + {% hook 'variants' with { form: variant } %} + {% endfor %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant.html.twig new file mode 100644 index 0000000000..21fb4987c6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant.html.twig @@ -0,0 +1,25 @@ +{% set form = hookable_metadata.context.form %} + +
+
+
+ {% for optionValue in form.optionValues %} + {{ optionValue.vars.label|trans }}: {{ optionValue.vars.value }} + {% endfor %} +
+ {% if form.vars.value.id is null %} + {{- form_row(form.vars.button_delete, sylius_test_form_attribute('delete-button')|sylius_merge_recursive({'attr': {'class': 'btn-close'}})) -}} + {% endif %} +
+
+
+
+ {% hook 'variant#left' %} +
+ +
+ {% hook 'variant#right' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/channel_pricings.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/channel_pricings.html.twig new file mode 100644 index 0000000000..d9f090c44a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/channel_pricings.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.channelPricings) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/code.html.twig new file mode 100644 index 0000000000..640c088b05 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/code.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/name.html.twig new file mode 100644 index 0000000000..0ad243c51a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/form/variants/variant/name.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.name) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..c7ab254123 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/breadcrumbs.html.twig @@ -0,0 +1,11 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set product = hookable_metadata.context.resource %} + +{{ _breadcrumbs.default([ + { name: 'sylius.ui.dashboard'|trans, url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index'), active: false }, + { name: product.name|default(product.code), url: path('sylius_admin_product_show', {'id': product.id }), active: false }, + { name: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': product.id }), active: false }, + { name: 'sylius.ui.generate'|trans, active: true }, +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/title_block/actions/generate.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/title_block/actions/generate.html.twig new file mode 100644 index 0000000000..bf4439b624 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/title_block/actions/generate.html.twig @@ -0,0 +1,4 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} +{% set form = hookable_metadata.context.form %} + +{{ _button.primary(sylius_test_form_attribute('generate-button')|merge({ text: 'sylius.ui.generate'|trans, type: 'submit', form: form.vars.id, disabled: form.variants is empty })) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/title_block/title.html.twig new file mode 100644 index 0000000000..1cf14366f6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/generate_variants/header/title_block/title.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +
+
+ {{ _header.h1('sylius.ui.generate_variants'|trans) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/grid/action/generate_variants.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/grid/action/generate_variants.html.twig new file mode 100644 index 0000000000..1f632205d9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/grid/action/generate_variants.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path('sylius_admin_product_variant_generate', {'productId': options.product.id})) %} + + + {{ icon({ icon: 'arrows-split', class: 'icon icon-tabler' }) }} + {{ 'sylius.ui.generate'|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/main_taxon.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/main_taxon.html.twig new file mode 100644 index 0000000000..0d1b545332 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/main_taxon.html.twig @@ -0,0 +1,9 @@ +{% if data.name is defined %} + {{ data.name }} +{% else %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + + + {{ _icon({ icon: 'exclamation-circle' }) }} {{ 'sylius.ui.no_main_taxon'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/name.html.twig new file mode 100644 index 0000000000..e426e87783 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/name.html.twig @@ -0,0 +1,9 @@ +{% if data is not null %} + {{ data }} +{% else %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + + + {{ _icon({ icon: 'exclamation-circle' }) }} {{ 'sylius.ui.missing_translation'|trans }} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/product_image.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/product_image.html.twig new file mode 100644 index 0000000000..8b1792edb7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/grid/field/product_image.html.twig @@ -0,0 +1,5 @@ +{% import '@SyliusAdmin/shared/helper/product.html.twig' as _product %} + +
+ {{ _product.image(data) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/product_attribute_autocomplete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/product_attribute_autocomplete.html.twig new file mode 100644 index 0000000000..7b2dedcd32 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/product_attribute_autocomplete.html.twig @@ -0,0 +1,10 @@ +
+ +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/scripts.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/scripts.html.twig new file mode 100644 index 0000000000..09c85629b9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/scripts.html.twig @@ -0,0 +1 @@ +{{ encore_entry_script_tags('admin-product-entry', null, 'admin') }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..6dd056429b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/header/title_block/actions.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'actions' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..262db20eae --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/header/title_block/title.html.twig @@ -0,0 +1,7 @@ +{% set product = hookable_metadata.context.resource %} + +
+
+

{{ product.name }}

+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body.html.twig new file mode 100644 index 0000000000..760bb977c6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'page_body' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/associations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/associations.html.twig new file mode 100644 index 0000000000..c7085ec70b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/associations.html.twig @@ -0,0 +1,23 @@ +{% set product = hookable_metadata.context.resource %} + +
+
+
+ {{ 'sylius.ui.associations'|trans }} +
+
+
+ {% if product.associations is empty %} + {{ 'sylius.ui.no_associations_to_display'|trans }} + {% else %} + {% for association in product.associations %} + {{ association.type.name }}: +
    + {% for associatedProduct in association.associatedProducts %} +
  • {{ associatedProduct.name }}
  • + {% endfor %} +
+ {% endfor %} + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details.html.twig new file mode 100644 index 0000000000..490658ac58 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details.html.twig @@ -0,0 +1,14 @@ +{% set product = hookable_metadata.context.resource %} +{% set channels = [] %} +{% for channel in product.channels %} + {% set channels = channels|merge({ (channel.code): channel }) %} +{% endfor %} + +
+
+
+ {{ 'sylius.ui.details'|trans }} +
+
+ {% hook 'details' with { product, channels } %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/configurable_product.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/configurable_product.html.twig new file mode 100644 index 0000000000..4cb463fda2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/configurable_product.html.twig @@ -0,0 +1,146 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set product = hookable_metadata.context.product %} + +{% if product.isConfigurable() %} + {% set channels = hookable_metadata.context.channels %} + +
+ + + + + + + + + + + + + + + + {% for variant in product.variants %} + + + + + + + + + + + + + + + {% endfor %} + +
{{ 'sylius.ui.product'|trans }}{{ 'sylius.ui.enabled'|trans }}{{ 'sylius.ui.options'|trans }}{{ 'sylius.ui.tracked'|trans }}{{ 'sylius.ui.shipping_required'|trans }}{{ 'sylius.ui.tax_category'|trans }}{{ 'sylius.ui.current_stock'|trans }}
+ + +
+
+ {% if product.imagesByType('thumbnail') is not empty %} + {% set path = product.imagesByType('thumbnail').first.path|imagine_filter(filter|default('sylius_admin_product_thumbnail')) %} + {% elseif product.images.first %} + {% set path = product.images.first.path|imagine_filter(filter|default('sylius_admin_product_thumbnail')) %} + {% else %} + {% set path = asset('build/admin/images/200x200.png', 'admin') %} + {% endif %} + + {{ product.name }} +
+
+
{{ variant.name }}
+
{{ variant.code }}
+
+
+
+ + {% include '@SyliusAdmin/shared/grid/field/boolean.html.twig' with { data: variant.enabled } %} + + +
+ {% for option in variant.optionValues %} + {{ option.name }}: {{ option.value }} + {% endfor %} +
+
+ + {% include '@SyliusAdmin/shared/grid/field/boolean.html.twig' with { data: variant.tracked } %} + + + + {% include '@SyliusAdmin/shared/grid/field/boolean.html.twig' with { data: variant.shippingRequired } %} + + {{ variant.taxCategory }}{{ variant.onHand }} + + {{ _icon({ icon: 'pencil' }) }} + {{ 'sylius.ui.edit'|trans }} + +
+
+
+
+
{{ 'sylius.ui.pricing'|trans }}
+
+
+ + + + + + + + + + + + + {% for channelPricing in variant.channelPricings %} + {% set channel = attribute(channels, channelPricing.channelCode) %} + {% set currencyCode = channel.baseCurrency.code %} + {% set price = channelPricing.price %} + {% set originalPrice = channelPricing.originalPrice ?? 0 %} + {% set lowestPriceBeforeDiscount = channelPricing.lowestPriceBeforeDiscount %} + + + + + + + + + + {% endfor %} + +
{{ 'sylius.ui.channel'|trans }}{{ 'sylius.ui.price'|trans }}{{ 'sylius.ui.original_price'|trans }}{{ 'sylius.ui.lowest_price_before_discount'|trans }}{{ 'sylius.ui.discounted_by'|trans }}
+ + {{ channel.name }} + {{ _money.format(price, currencyCode) }}{{ _money.format(originalPrice, currencyCode) }}{% if lowestPriceBeforeDiscount != null %}{{ _money.format(lowestPriceBeforeDiscount, currencyCode) }}{% else %} - {% endif %} +
    + {% for promotion in channelPricing.appliedPromotions %} +
  • {{ promotion.name }}
  • + {% endfor %} +
+
+ + {{ 'sylius.ui.price_history'|trans }} + +
+
+
+
+ {% hook 'configurable_product' with { variant } %} +
+
+
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/shared/shipping.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/shared/shipping.html.twig new file mode 100644 index 0000000000..b1c91c1303 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/shared/shipping.html.twig @@ -0,0 +1,59 @@ +{% set variant = hookable_metadata.context.variant %} + +
+
{{ 'sylius.ui.shipping'|trans }}
+
+
+
+
+
{{ 'sylius.ui.shipping_category'|trans }}:
+
+ {% if variant.shippingCategory is null %} + {{ 'sylius.ui.no_shipping_category'|trans }} + {% else %} + {{ variant.shippingCategory }} + {% endif %} +
+
+
+
{{ 'sylius.ui.width'|trans }}:
+
+ {% if variant.width is null %} + {{ 'sylius.ui.no_width'|trans }} + {% else %} + {{ variant.width }} + {% endif %} +
+
+
+
{{ 'sylius.ui.height'|trans }}:
+
+ {% if variant.height is null %} + {{ 'sylius.ui.no_height'|trans }} + {% else %} + {{ variant.height }} + {% endif %} +
+
+
+
{{ 'sylius.ui.depth'|trans }}:
+
+ {% if variant.depth is null %} + {{ 'sylius.ui.no_depth'|trans }} + {% else %} + {{ variant.depth }} + {% endif %} +
+
+
+
{{ 'sylius.ui.weight'|trans }}:
+
+ {% if variant.weight is null %} + {{ 'sylius.ui.no_weight'|trans }} + {% else %} + {{ variant.weight }} + {% endif %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/simple_product.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/simple_product.html.twig new file mode 100644 index 0000000000..8823061961 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/details/simple_product.html.twig @@ -0,0 +1,71 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} +{% import '@SyliusAdmin/shared/helper/money.html.twig' as _money %} + +{% set product = hookable_metadata.context.product %} + +{% if product.isSimple() %} + {% set variant = product.variants.first %} + {% set channels = hookable_metadata.context.channels %} + + + + + +
+
+
+
+
{{ 'sylius.ui.pricing'|trans }}
+
+
+ + + + + + + + + + + + + {% for channelPricing in variant.channelPricings %} + {% set channel = attribute(channels, channelPricing.channelCode) %} + {% set currencyCode = channel.baseCurrency.code %} + {% set price = channelPricing.price %} + {% set originalPrice = channelPricing.originalPrice ?? 0 %} + {% set lowestPriceBeforeDiscount = channelPricing.lowestPriceBeforeDiscount %} + + + + + + + + + + {% endfor %} + +
{{ 'sylius.ui.channel'|trans }}{{ 'sylius.ui.price'|trans }}{{ 'sylius.ui.original_price'|trans }}{{ 'sylius.ui.lowest_price_before_discount'|trans }}{{ 'sylius.ui.discounted_by'|trans }}
+ + {{ channel.name }} + {{ _money.format(price, currencyCode) }}{{ _money.format(originalPrice, currencyCode) }}{% if lowestPriceBeforeDiscount != null %}{{ _money.format(lowestPriceBeforeDiscount, currencyCode) }}{% else %} - {% endif %} +
    + {% for promotion in channelPricing.appliedPromotions %} +
  • {{ promotion.name }}
  • + {% endfor %} +
+
+ + {{ 'sylius.ui.price_history'|trans }} + +
+
+
+
+ {% hook 'simple_product' with { variant } %} +
+
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy.html.twig new file mode 100644 index 0000000000..0fc41cc643 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy.html.twig @@ -0,0 +1,14 @@ +{% set product = hookable_metadata.context.resource %} + +
+
+
+ {{ 'sylius.ui.taxonomy'|trans }} +
+
+
+
+ {% hook 'taxonomy' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy/main_taxon.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy/main_taxon.html.twig new file mode 100644 index 0000000000..2aa6f38766 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy/main_taxon.html.twig @@ -0,0 +1,12 @@ +{% set product = hookable_metadata.context.resource %} + +
+
{{ 'sylius.ui.main_taxon'|trans }}:
+
+ {% if product.mainTaxon is null %} + {{ 'sylius.ui.no_main_taxon'|trans }} + {% else %} + {{ product.mainTaxon.fullName }} + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy/product_taxons.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy/product_taxons.html.twig new file mode 100644 index 0000000000..de3ca0a212 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/taxonomy/product_taxons.html.twig @@ -0,0 +1,10 @@ +{% set product = hookable_metadata.context.resource %} + +
+
{{ 'sylius.ui.product_taxons'|trans }}:
+
+ {% for productTaxon in product.productTaxons %} +
{{ productTaxon.taxon.fullName }}
+ {% endfor %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/description.html.twig new file mode 100644 index 0000000000..f927fa8c4f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/description.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.description'|trans }}:
+
{{ hookable_metadata.context.productTranslation.description }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/meta_description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/meta_description.html.twig new file mode 100644 index 0000000000..1736ad65f0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/meta_description.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.meta_description'|trans }}:
+
{{ hookable_metadata.context.productTranslation.metaDescription }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/meta_keywords.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/meta_keywords.html.twig new file mode 100644 index 0000000000..14f06360b9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/meta_keywords.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.meta_keywords'|trans }}:
+
{{ hookable_metadata.context.productTranslation.metaKeywords }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/product_name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/product_name.html.twig new file mode 100644 index 0000000000..ac7147f4d6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/product_name.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.name'|trans }}:
+
{{ hookable_metadata.context.productTranslation.name }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/short_description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/short_description.html.twig new file mode 100644 index 0000000000..d502c6a0ef --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/short_description.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.form.product.short_description'|trans }}:
+
{{ hookable_metadata.context.productTranslation.shortDescription }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/slug.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/slug.html.twig new file mode 100644 index 0000000000..f19580a336 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translation_content/slug.html.twig @@ -0,0 +1,4 @@ +
+
{{ 'sylius.ui.slug'|trans }}:
+
{{ hookable_metadata.context.productTranslation.slug }}
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translations.html.twig new file mode 100644 index 0000000000..0edfa42d97 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product/show/content/page_body/translations.html.twig @@ -0,0 +1,34 @@ +{% set product = hookable_metadata.context.resource %} + +
+
+ {% for productTranslation in product.translations %} + {% set locale = productTranslation.locale %} + +
+

+ +

+
+
+
+
+
+
{{ 'sylius.ui.content'|trans }}
+
+
+
+ {% hook 'translations' with { productTranslation } %} +
+
+
+
+
+
+
+ {% endfor %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form.html.twig new file mode 100644 index 0000000000..c2950dbf8a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form.html.twig @@ -0,0 +1,20 @@ +{% set form = hookable_metadata.context.form %} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+
+
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: false}) }} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form/code.html.twig new file mode 100644 index 0000000000..0703ad28ff --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form/code.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form/translations.html.twig new file mode 100644 index 0000000000..7e71a76f4e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_association_type/form/translations.html.twig @@ -0,0 +1,14 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +
+ {% set body %} + {% verbatim %} +
+
+ {{ form_row(translationForm.name, sylius_test_form_attribute('name', locale)) }} +
+
+ {% endverbatim %} + {% endset %} + {{ _translations.default(hookable_metadata.context.form.translations, body) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_attribute/grid/action/create.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_attribute/grid/action/create.html.twig new file mode 100644 index 0000000000..7e44d35dc7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_attribute/grid/action/create.html.twig @@ -0,0 +1,12 @@ +{% import '@SyliusAdmin/shared/helper/dropdown.html.twig' as _dropdown %} + +{{ _dropdown.list( + { + direction: 'down-end', + button: { text: 'sylius.ui.create'|trans, icon: 'plus' }, + }, + sylius_attribute_types()|map((value, key) => { + title: ('sylius.form.attribute_type.' ~ value.type)|trans, + url: path(grid.requestConfiguration.getRouteName('create'), { type: key }) + }) +) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_review/grid/field/rating.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_review/grid/field/rating.html.twig new file mode 100644 index 0000000000..aac977dd11 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_review/grid/field/rating.html.twig @@ -0,0 +1 @@ +{{ data }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_review/grid/field/state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_review/grid/field/state.html.twig new file mode 100644 index 0000000000..7a7b00d5a9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_review/grid/field/state.html.twig @@ -0,0 +1,13 @@ +{% + set viewOptions = { + accepted: { color: 'bg-green-lt' }, + new: { color: '' }, + rejected: { color: 'bg-red-lt' }, +} +%} + +{% set value = 'sylius.ui.' ~ data %} + + + {{ value|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form.html.twig new file mode 100644 index 0000000000..14144d0ae8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form.html.twig @@ -0,0 +1,19 @@ +{% if form is not defined %} + {% set form = hookable_metadata.context.form %} +{% endif %} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} +
+ {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form, sylius_test_form_attribute('form-validation-errors')) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} +
+ {{ form_end(form, {render_rest: hookable.configuration.render_rest|default(false)}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/create/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/create/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..3bcb8c1d2f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/create/header/breadcrumbs.html.twig @@ -0,0 +1,12 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set product_variant = hookable_metadata.context.resource %} +{% set product = product_variant.product %} + +{{ _breadcrumbs.default([ + { name: 'sylius.ui.dashboard'|trans, url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index'), active: false }, + { name: product.name|default(product.code), url: path('sylius_admin_product_show', {'id': product.id }), active: false }, + { name: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': product.id }), active: false }, + { name: 'sylius.ui.new'|trans, active: true } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..3bcb8c1d2f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/header/breadcrumbs.html.twig @@ -0,0 +1,12 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set product_variant = hookable_metadata.context.resource %} +{% set product = product_variant.product %} + +{{ _breadcrumbs.default([ + { name: 'sylius.ui.dashboard'|trans, url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index'), active: false }, + { name: product.name|default(product.code), url: path('sylius_admin_product_show', {'id': product.id }), active: false }, + { name: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': product.id }), active: false }, + { name: 'sylius.ui.new'|trans, active: true } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/update/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/update/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..b24f216f0d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/content/update/header/breadcrumbs.html.twig @@ -0,0 +1,12 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set product_variant = hookable_metadata.context.resource %} +{% set product = product_variant.product %} + +{{ _breadcrumbs.default([ + { name: 'sylius.ui.dashboard'|trans, url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index'), active: false }, + { name: product.name|default(product.code), url: path('sylius_admin_product_show', {'id': product.id }), active: false }, + { name: 'sylius.ui.variants'|trans, url: path('sylius_admin_product_variant_index', {'productId': product.id }), active: false }, + { name: 'sylius.ui.edit'|trans, active: true } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections.html.twig new file mode 100644 index 0000000000..b01a02870e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'sections' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/channel_pricing.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/channel_pricing.html.twig new file mode 100644 index 0000000000..eda0410634 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/channel_pricing.html.twig @@ -0,0 +1,54 @@ +{% set product_variant = hookable_metadata.context.form.vars.data%} +{% import '@SyliusAdmin/shared/helper/channelPricings.html.twig' as _channelPricings %} + +
+
+
+

{{ 'sylius.ui.price_details'|trans }}

+

{{ 'sylius.ui.original_price_details'|trans }}

+

{{ 'sylius.ui.minimum_price_details'|trans }}

+
+ {% set body %} + {% verbatim %} +
+
+ {% set isChannelPricingInvalid = channelPricingForm.vars.errors.form.parent.errors is not empty %} + + {% if isChannelPricingInvalid %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + + + {% endif %} + {% if channelCode not in product_variant.product.channels|map(channel => channel.code) %} +
+ {{ 'sylius.ui.product.product_not_active_in_channel'|trans }} +
+ {% endif %} +
+
+
+
+ {{ form_row(channelPricingForm.price) }} +
+
+ {{ form_row(channelPricingForm.originalPrice) }} +
+
+ {{ form_row(channelPricingForm.minimumPrice) }} +
+
+ {% endverbatim %} + {% endset %} + {{ _channelPricings.default(hookable_metadata.context.form.channelPricings, product_variant, body) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/details.html.twig new file mode 100644 index 0000000000..d84ee6bdbb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/details.html.twig @@ -0,0 +1,40 @@ +{% set form = hookable_metadata.context.form %} + +
+
+
+

+ {{ 'sylius.ui.details'|trans }} +

+
+
+
+ {{ form_row(form.code) }} + {{ form_row(form.enabled) }} +
+
+ {{ form_row(form.shippingCategory) }} + {{ form_row(form.shippingRequired) }} +
+ {% if form.optionValues is defined and form.optionValues|length > 0 %} +
+

{{ 'sylius.ui.options'|trans }}

+ {% for option_form in form.optionValues %} + {{ form_row(option_form) }} + {% endfor %} +
+ {% endif %} +
+
+
+

{{ 'sylius.ui.properties'|trans }}

+ {{ form_row(form.height) }} + {{ form_row(form.width) }} + {{ form_row(form.depth) }} + {{ form_row(form.weight) }} +
+
+
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/inventory.html.twig new file mode 100644 index 0000000000..46b0258eda --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/inventory.html.twig @@ -0,0 +1,14 @@ +{% set form = hookable_metadata.context.form %} + +
+
+
+

{{ 'sylius.ui.inventory'|trans }}

+
+
+ {{ form_row(form.onHand) }} + {{ form_row(form.tracked) }} + {{ form_row(form.version) }} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/taxes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/taxes.html.twig new file mode 100644 index 0000000000..63a2311deb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/taxes.html.twig @@ -0,0 +1,12 @@ +{% set form = hookable_metadata.context.form %} + +
+
+
+

{{ 'sylius.ui.taxes'|trans }}

+
+
+ {{ form_row(form.taxCategory) }} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/translations.html.twig new file mode 100644 index 0000000000..bbc69c52c9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/sections/translations.html.twig @@ -0,0 +1,16 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +
+
+ {% set body %} + {% verbatim %} +
+
+ {{ form_row(translationForm.name) }} +
+
+ {% endverbatim %} + {% endset %} + {{ _translations.default(hookable_metadata.context.form.translations, body, {accordionId: 'product-variant-translations'}) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation.html.twig new file mode 100644 index 0000000000..560cf9f794 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation.html.twig @@ -0,0 +1,7 @@ +
+
+
+ {% hook 'side_navigation' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/channel_pricing.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/channel_pricing.html.twig new file mode 100644 index 0000000000..a2a606c308 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/channel_pricing.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/details.html.twig new file mode 100644 index 0000000000..8439eea5ca --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/details.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/inventory.html.twig new file mode 100644 index 0000000000..2eda254a61 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/inventory.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/taxes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/taxes.html.twig new file mode 100644 index 0000000000..08dc2ebe8b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/taxes.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/translations.html.twig new file mode 100644 index 0000000000..29079f4e1b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/form/side_navigation/translations.html.twig @@ -0,0 +1,10 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/action/update_positions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/action/update_positions.html.twig new file mode 100644 index 0000000000..07aea4d46e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/action/update_positions.html.twig @@ -0,0 +1,15 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/inventory.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/inventory.html.twig new file mode 100644 index 0000000000..5192a4bd58 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/inventory.html.twig @@ -0,0 +1,8 @@ +{% if data.isTracked %} + {{ data.onHand }} {{ 'sylius.ui.available_on_hand'|trans }} + {% if data.onHold > 0 %} + {{ data.onHold }} {{ 'sylius.ui.reserved'|trans }} + {% endif %} +{% else %} + {{ 'sylius.ui.not_tracked'|trans }} +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/name.html.twig similarity index 73% rename from src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/name.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/name.html.twig index 70d27b00e7..887c8e9d47 100644 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/ProductVariant/Grid/Field/name.html.twig +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/name.html.twig @@ -8,7 +8,10 @@ {{ translation.name }} {% else %} - {% include '@SyliusAdmin/Common/_missingTranslation.html.twig' %} + + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + {{ _icon({ icon: 'exclamation-circle' }) }} {{ 'sylius.ui.missing_translation'|trans }} + {% endif %} {% else %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/position.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/position.html.twig new file mode 100644 index 0000000000..a715b56e5d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/grid/field/position.html.twig @@ -0,0 +1 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/product_variant/index/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/product_variant/index/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..906a8bf935 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/product_variant/index/content/header/breadcrumbs.html.twig @@ -0,0 +1,11 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set configuration = hookable_metadata.context.resources.requestConfiguration %} +{% set product = configuration.vars.product %} + +{{ _breadcrumbs.default([ + { name: 'Dashboard', url: path('sylius_admin_dashboard'), active: false }, + { name: 'sylius.ui.products'|trans, url: path('sylius_admin_product_index'), active: false }, + { name: product.name|default(product.code), url: path('sylius_admin_product_show', {'id': product.id }), active: false }, + { name: 'sylius.ui.variants'|trans, active: true }, +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form.html.twig new file mode 100644 index 0000000000..213a880c6c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form.html.twig @@ -0,0 +1,16 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\TwigComponent\Promotion\FormComponent #} + +{% form_theme form '@SyliusAdmin/promotion/form_theme.html.twig' %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: hookable.configuration.render_rest|default(false)}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections.html.twig new file mode 100644 index 0000000000..86a74da537 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections.html.twig @@ -0,0 +1 @@ +{% hook 'sections' %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration.html.twig new file mode 100644 index 0000000000..3444268c12 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration.html.twig @@ -0,0 +1,20 @@ +
+
+
+ {{ 'sylius.ui.configuration'|trans }} +
+
+
+
+ {% hook 'configuration' %} + +
+ {% hook 'configuration#left' %} +
+ +
+ {% hook 'configuration#right' %} +
+
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/applies_to_discounted.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/applies_to_discounted.html.twig new file mode 100644 index 0000000000..d6ea028675 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/applies_to_discounted.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.appliesToDiscounted, {help_attr: { 'class': 'form-hint' }}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/coupon_based.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/coupon_based.html.twig new file mode 100644 index 0000000000..8016901e0e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/coupon_based.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.couponBased) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/ends_at.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/ends_at.html.twig new file mode 100644 index 0000000000..3e4004c07e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/ends_at.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.endsAt) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/exclusive.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/exclusive.html.twig new file mode 100644 index 0000000000..3eb8fb3ace --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/exclusive.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.exclusive) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/header.html.twig new file mode 100644 index 0000000000..923f5d4a1c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/header.html.twig @@ -0,0 +1 @@ +
{{ 'sylius.ui.options'|trans }}
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/priority.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/priority.html.twig new file mode 100644 index 0000000000..2906136b50 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/priority.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.priority) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/starts_at.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/starts_at.html.twig new file mode 100644 index 0000000000..e389f6239a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/starts_at.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.startsAt) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/usage_limit.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/usage_limit.html.twig new file mode 100644 index 0000000000..b4c512b308 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/configuration/usage_limit.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.usageLimit, sylius_test_form_attribute('usage-limit')) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general.html.twig new file mode 100644 index 0000000000..85638eb426 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general.html.twig @@ -0,0 +1,12 @@ +
+
+
+ {{ 'sylius.ui.general'|trans }} +
+
+
+
+ {% hook 'general' %} +
+
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/channels.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/channels.html.twig new file mode 100644 index 0000000000..a6f41e2711 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/channels.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.channels) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/code.html.twig new file mode 100644 index 0000000000..69861ccd02 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/code.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.code) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/description.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/description.html.twig new file mode 100644 index 0000000000..f3de69a3de --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/description.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.description, sylius_test_form_attribute('description')) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/name.html.twig new file mode 100644 index 0000000000..ff93f7b852 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/general/name.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(hookable_metadata.context.form.name) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions.html.twig new file mode 100644 index 0000000000..38990ab70a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'rules_and_actions' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions/actions.html.twig new file mode 100644 index 0000000000..67489889e5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions/actions.html.twig @@ -0,0 +1,19 @@ +
+
+
+
+ {{ 'sylius.ui.actions'|trans }} +
+
+
+
+ {{ form_row(hookable_metadata.context.form.actions, {label: false}) }} + + {% hook 'actions' %} +
+
+ +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions/rules.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions/rules.html.twig new file mode 100644 index 0000000000..8312f87cc9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/rules_and_actions/rules.html.twig @@ -0,0 +1,19 @@ +
+
+
+
+ {{ 'sylius.ui.rules'|trans }} +
+
+
+
+ {{ form_row(hookable_metadata.context.form.rules, {label: false}) }} + + {% hook 'rules' %} +
+
+ +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/translations.html.twig new file mode 100644 index 0000000000..320f8e4886 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form/sections/translations.html.twig @@ -0,0 +1,5 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +
+ {{ _translations.default(hookable_metadata.context.form.translations, null, {accordionId: 'promotion-translations'}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/form_theme.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/form_theme.html.twig new file mode 100644 index 0000000000..417c6a4c16 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/form_theme.html.twig @@ -0,0 +1,54 @@ +{% extends '@SyliusAdmin/shared/form_theme.html.twig' %} + +{%- block live_collection_widget -%} + {{ block('form_widget') }} +{%- endblock live_collection_widget -%} + +{%- block sylius_promotion_rule_row -%} +
+ {{- form_errors(form) -}} + {{- form_row(form.type) -}} +
+
+
{{ (sylius_admin_get_promotion_rule_label(form.type.vars.data))|trans }}
+ {{- form_row(button_delete, sylius_test_form_attribute('delete')|sylius_merge_recursive({'attr': {'class': 'btn-close'}})) -}} +
+
+ {{- form_row(form.configuration, {'label': false}) -}} +
+
+
+{%- endblock sylius_promotion_rule_row -%} + +{%- block sylius_promotion_action_row -%} +
+ {{- form_errors(form) -}} + {{- form_row(form.type) -}} +
+
+
{{ (sylius_admin_get_promotion_action_label(form.type.vars.data))|trans }}
+ {{- form_row(button_delete, sylius_test_form_attribute('delete')|sylius_merge_recursive({'attr': {'class': 'btn-close'}})) -}} +
+
+ {{- form_row(form.configuration, {'label': false}) -}} +
+
+
+{%- endblock sylius_promotion_action_row -%} + +{% block add_button_row %} + {% if types is not empty %} + + {% endif %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/grid/field/priority.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/grid/field/priority.html.twig new file mode 100644 index 0000000000..aac977dd11 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/grid/field/priority.html.twig @@ -0,0 +1 @@ +{{ data }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/promotion/grid/field/usage.html.twig b/src/Sylius/Bundle/AdminBundle/templates/promotion/grid/field/usage.html.twig new file mode 100644 index 0000000000..281c606eff --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/promotion/grid/field/usage.html.twig @@ -0,0 +1,42 @@ +{% if data.usageLimit is empty %} +
+ n/a +
+{% else %} + {% if data.used == data.usageLimit %} + {% set color = 'danger' %} + {% elseif data.used > data.usageLimit/2 %} + {% set color = 'warning' %} + {% else %} + {% set color = 'success' %} + {% endif %} + +
+
+
+
+
{{ data.used }} / {{ data.usageLimit }}
+
+{% endif %} +{#{% if data.usageLimit is empty %}#} +{# #} +{# {{ data.used }}#} +{# #} +{# /#} +{# #} +{#{% else %}#} +{# {% set color = 'teal' %}#} + +{# {% if data.used == data.usageLimit %}#} +{# {% set color = 'red' %}#} +{# {% elseif data.used > data.usageLimit/2 %}#} +{# {% set color = 'yellow' %}#} +{# {% endif %}#} +{# #} +{# {{ data.used }}#} +{# #} +{# /#} +{# #} +{# {{ data.usageLimit }}#} +{# #} +{#{% endif %}#} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login.html.twig new file mode 100644 index 0000000000..4c5f95b191 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login.html.twig @@ -0,0 +1,13 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% block title %}Sylius | {{ 'sylius.ui.administration_panel_login'|trans }}{% endblock %} + +{% block body_class %}d-flex flex-column{% endblock %} + +{% block body %} +
+
+ {% hook 'sylius_admin.security.login' with { form, last_error, last_username } %} +
+
+{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content.html.twig new file mode 100644 index 0000000000..b17b893d6e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'content' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form.html.twig new file mode 100644 index 0000000000..8dbe636aba --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form.html.twig @@ -0,0 +1,8 @@ +{% set form = hookable_metadata.context.form %} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_start(form, {'action': path('sylius_admin_login_check'), 'attr': {'class': 'ui large loadable form', 'novalidate': 'novalidate'}}) }} + {% hook 'form' with { form } %} + +{{ form_end(form, {'render_rest': false}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/error.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/error.html.twig new file mode 100644 index 0000000000..06b78857c5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/error.html.twig @@ -0,0 +1,7 @@ +{% set lastError = hookable_metadata.context.last_error|default(null) %} + +{% if lastError is not null %} +
+ {{ lastError.messageKey|trans }} +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/password.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/password.html.twig new file mode 100644 index 0000000000..eac61d9ed0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/password.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form._password) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/remember_me.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/remember_me.html.twig new file mode 100644 index 0000000000..669c346c07 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/remember_me.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form._remember_me) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/submit.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/submit.html.twig new file mode 100644 index 0000000000..ad7d911c56 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/submit.html.twig @@ -0,0 +1,3 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{{ _button.primary({ text: 'sylius.ui.login'|trans, type: 'submit', class: 'btn btn-primary w-100' }) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/username.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/username.html.twig new file mode 100644 index 0000000000..9dc070cf1d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/form/username.html.twig @@ -0,0 +1,3 @@ +{% set last_username = hookable_metadata.context.last_username|default('') %} + +{{ form_row(hookable_metadata.context.form._username, { 'value': last_username }) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/content/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/header.html.twig new file mode 100644 index 0000000000..3ebc72019e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/content/header.html.twig @@ -0,0 +1 @@ +

{{ 'sylius.ui.login_to_your_account'|trans }}

diff --git a/src/Sylius/Bundle/AdminBundle/templates/security/login/logo.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/login/logo.html.twig new file mode 100644 index 0000000000..3a44a06cd1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/security/login/logo.html.twig @@ -0,0 +1,3 @@ +
+ Sylius +
diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/requestPasswordReset.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/request_password_reset.html.twig similarity index 100% rename from src/Sylius/Bundle/AdminBundle/Resources/views/Security/requestPasswordReset.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/security/request_password_reset.html.twig diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Security/resetPassword.html.twig b/src/Sylius/Bundle/AdminBundle/templates/security/reset_password.html.twig similarity index 100% rename from src/Sylius/Bundle/AdminBundle/Resources/views/Security/resetPassword.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/security/reset_password.html.twig diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/components/navbar/notifications.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/components/navbar/notifications.html.twig new file mode 100644 index 0000000000..4e1fa3fa9f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/components/navbar/notifications.html.twig @@ -0,0 +1,53 @@ +{# Rendered by \Sylius\Bundle\AdminBundle\TwigComponent\Shared\Navbar\NotificationsComponent #} + +{% import '@SyliusAdmin/shared/helper/dropdown.html.twig' as dropdown %} +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/components/navbar/user.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/components/navbar/user.html.twig new file mode 100644 index 0000000000..598715e238 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/components/navbar/user.html.twig @@ -0,0 +1,20 @@ +{% import '@SyliusAdmin/shared/helper/avatar.html.twig' as avatar %} +{% import '@SyliusAdmin/shared/helper/dropdown.html.twig' as dropdown %} + +{% set dropdown_trigger %} +
+
+ {% if user.avatar.path is not defined or user.avatar.path is empty %} + {{ avatar.small() }} + {% else %} + {{ avatar.small(user.avatar.path|imagine_filter('sylius_admin_admin_user_avatar_thumbnail')) }} + {% endif %} +
+
+
Hello
+
{{ user.firstName }}
+
+
+{% endset %} + +{{ dropdown.list({ customTrigger: dropdown_trigger, direction: 'down-end' }, menuItems) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content.html.twig new file mode 100644 index 0000000000..1f91de987c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'content' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/flashes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/flashes.html.twig new file mode 100644 index 0000000000..d48b1a503a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/flashes.html.twig @@ -0,0 +1,36 @@ +{% set session = _context.app.session|default(null) %} + +{% if session is not null and session.started %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} +
+ {% for type in ['success', 'error', 'info', 'warning'] %} + {% for flash in session.flashbag.get(type) %} + + {% endfor %} + {% endfor %} +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header.html.twig new file mode 100644 index 0000000000..5709118ead --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header.html.twig @@ -0,0 +1,5 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block.html.twig new file mode 100644 index 0000000000..2694cce12f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block.html.twig @@ -0,0 +1,3 @@ +
+ {% hook 'title_block' %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..ca3e9324e7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions.html.twig @@ -0,0 +1,13 @@ +{% import '@SyliusAdmin/shared/helper/dropdown.html.twig' as _dropdown %} + +{% set resources = hookable_metadata.context.resources %} + +
+
+ {% if resources.definition.actionGroups.main is defined %} + {% for action in resources.definition.getEnabledActions('main') %} + {{ sylius_grid_render_action(resources, action, null) }} + {% endfor %} + {% endif %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/cancel.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/cancel.html.twig new file mode 100644 index 0000000000..873e8f42f0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/cancel.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{% set configuration = hookable_metadata.context.configuration %} + +{% set index_url = path( + configuration.vars.index.route.name|default(configuration.getRouteName('index')), + configuration.vars.index.route.parameters|default(configuration.vars.route.parameters|default({})) +) %} + +{{ _button.cancel(sylius_test_form_attribute('cancel-changes-button')|merge({ text: 'sylius.ui.cancel'|trans, url: index_url, class: 'btn' })) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/create.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/create.html.twig new file mode 100644 index 0000000000..db23ae45ed --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/create.html.twig @@ -0,0 +1,5 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{% set form = hookable_metadata.context.form %} + +{{ _button.primary({ text: 'sylius.ui.create'|trans, type: 'submit', form: form.vars.id }) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/update.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/update.html.twig new file mode 100644 index 0000000000..31bbaa3d2f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/actions/update.html.twig @@ -0,0 +1,9 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{{ _button.primary( + sylius_test_form_attribute('update-changes-button')|merge({ + text: 'sylius.ui.update'|trans, + type: 'submit', + form: hookable_metadata.context.form.vars.id + }) +) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..a4c933d704 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/content/header/title_block/title.html.twig @@ -0,0 +1,15 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +{% if hookable_metadata.context.has("metadata") %} + {% set metadata = hookable_metadata.context.metadata %} + {% set header = hookable_metadata.configuration.title|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} +{% else %} + {% set header = hookable_metadata.configuration.title %} +{% endif %} + + +
+
+ {{ _header.h1(header|trans) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar.html.twig new file mode 100644 index 0000000000..b8c8fb6501 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar.html.twig @@ -0,0 +1,5 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/items.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/items.html.twig new file mode 100644 index 0000000000..442c0f457f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/items.html.twig @@ -0,0 +1,3 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/items/user.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/items/user.html.twig new file mode 100644 index 0000000000..07ca8eeba0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/items/user.html.twig @@ -0,0 +1,3 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/menu.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/menu.html.twig new file mode 100644 index 0000000000..c1ffe4b588 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/menu.html.twig @@ -0,0 +1,3 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/menu/search.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/menu/search.html.twig new file mode 100644 index 0000000000..71b54aa5c6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/navbar/menu/search.html.twig @@ -0,0 +1,12 @@ +
+
+ + + + + + + + +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar.html.twig new file mode 100644 index 0000000000..e9bf1c3ffe --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar.html.twig @@ -0,0 +1,5 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/logo.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/logo.html.twig new file mode 100644 index 0000000000..d9768b7ac1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/logo.html.twig @@ -0,0 +1,5 @@ +

+ + Sylius + +

diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/menu.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/menu.html.twig new file mode 100644 index 0000000000..a54c82f5cd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/menu.html.twig @@ -0,0 +1,3 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/menu/menu.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/menu/menu.html.twig new file mode 100644 index 0000000000..85f6928e01 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/menu/menu.html.twig @@ -0,0 +1,104 @@ +{% extends 'knp_menu.html.twig' %} + +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% block root %} + +{% endblock %} + +{% block list %} + {% for item in item.children %} + {{ block('item') }} + {% endfor %} +{% endblock %} + +{% block item %} + {# building the class of the item #} + {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %} + {%- if matcher.isCurrent(item) %} + {%- set classes = classes|merge([options.currentClass]) %} + {%- elseif matcher.isAncestor(item, options.matchingDepth) %} + {%- set classes = classes|merge([options.ancestorClass]) %} + {%- endif %} + {%- if item.actsLikeFirst %} + {%- set classes = classes|merge([options.firstClass]) %} + {%- endif %} + {%- if item.actsLikeLast %} + {%- set classes = classes|merge([options.lastClass]) %} + {%- endif %} + + {% set isActive = matcher.isCurrent(item) or matcher.isAncestor(item, options.matchingDepth) %} + + {# Mark item as "leaf" (no children) or as "branch" (has children that are displayed) #} + {% if item.hasChildren and options.depth is not same as(0) %} + {% if options.branch_class is not empty and item.displayChildren %} + {%- set classes = classes|merge([options.branch_class]) %} + {% endif %} + {% elseif options.leaf_class is not empty %} + {%- set classes = classes|merge([options.leaf_class]) %} + {%- endif %} + + {%- set attributes = item.attributes %} + {%- if classes is not empty %} + {%- set attributes = attributes|merge({'class': classes|join(' ')}) %} + {%- endif %} + {% if item.hasChildren %} + + {% else %} + + {% endif %} +{% endblock %} + +{% block childrenList %} + {% for item in item.children %} + {{ block('childItem') }} + {% endfor %} +{% endblock %} + +{% block childItem %} + {%- set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %} + {%- set target = item.linkAttributes and item.linkAttributes['target'] ? item.linkAttributes['target'] : '_self' %} + {%- if matcher.isCurrent(item) %} + {%- set classes = classes|merge([options.currentClass]) %} + {%- endif %} + + {%- if classes is not empty %} + {%- set attributes = attributes|merge({'class': classes|join(' ')}) %} + {%- endif %} + + {% set isActive = matcher.isCurrent(item) %} + + + {{ item.label|trans }}{% if target == '_blank' %}{{ icon({ icon: 'external-link', class: 'icon icon-tabler icon-sm ms-1 mb-2 opacity-75' }) }}{% endif %} + +{% endblock %} + +{% block icon %} + {% set iconName = item.labelAttribute('icon') %} + {% if iconName %}{{ icon({ icon: iconName }) }}{% endif %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/user.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/user.html.twig new file mode 100644 index 0000000000..62c3a6de85 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/common/sidebar/user.html.twig @@ -0,0 +1,3 @@ +
+ {{ component('sylius_admin:navbar:user_dropdown') }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create.html.twig new file mode 100644 index 0000000000..98073030e5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create.html.twig @@ -0,0 +1,24 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% set prefixes = [ + 'sylius_admin.%resource_name%'|replace({'%resource_name%': resource_name|default(metadata.name)}), + 'sylius_admin.common' +] %} + +{% set header = metadata.applicationName ~ '.ui.' ~ metadata.pluralName %} + +{% block title %}{{ header|trans }} | {{ parent() }}{% endblock %} + +{% block body %} + {% hook 'create' with { _prefixes: prefixes, resource, metadata, configuration, form } %} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {% hook 'create#stylesheets' with { _prefixes: prefixes } %} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + {% hook 'create#javascripts' with { _prefixes: prefixes } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/form.html.twig new file mode 100644 index 0000000000..9e6307e41e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/form.html.twig @@ -0,0 +1,46 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{% set resource = hookable_metadata.context.resource %} +{% set configuration = hookable_metadata.context.configuration %} +{% set form = hookable_metadata.context.form %} + +{% set route = configuration.vars.route|default(null) %} +{% set indexRoute = configuration.vars.index.route|default(null) %} +{% set index_url = path( + indexRoute.name|default(_context.configuration.getRouteName('index')), + indexRoute.parameters|default(route.parameters|default({})) +) +%} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+
+ {% block content %} + {% set renderRest = hookable_metadata.configuration.render_rest %} + + {% if renderRest %} +
+
+ {% endif %} + {{ form_start(form, {'action': path(configuration.vars.route.name|default(configuration.getRouteName('create')), configuration.vars.route.parameters|default({})), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% block form_content %} + {% hook 'form' with { form } %} + {% endblock %} + {{ form_end(form, {'render_rest': renderRest}) }} + {% if renderRest %} +
+ +
+ {% endif %} + {% endblock %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..b416a669bb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/breadcrumbs.html.twig @@ -0,0 +1,21 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% if hookable_metadata.context.metadata is defined %} + {% set metadata = hookable_metadata.context.metadata %} + {% set resourceName = hookable_metadata.configuration.resource_name|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} +{% else %} + {% set resourceName = hookable_metadata.configuration.resource_name %} +{% endif %} + +{% set configuration = hookable_metadata.context.configuration %} +{% set index_url = path( + configuration.vars.index.route.name|default(configuration.getRouteName('index')), + configuration.vars.index.route.parameters|default(configuration.vars.route.parameters|default({})) +) +%} + +{{ _breadcrumbs.default([ + { name: 'Dashboard', url: path('sylius_admin_dashboard'), active: false }, + { name: resourceName, url: index_url, active: false }, + { name: 'sylius.ui.new'|trans, active: true} +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..5b85ba8cb2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/title_block/actions.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +
+
+ {% hook 'actions' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..4e28e70507 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/create/content/header/title_block/title.html.twig @@ -0,0 +1,18 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +{% if hookable_metadata.context.metadata is defined and hookable_metadata.context.configuration is defined %} + {% set configuration = hookable_metadata.context.configuration %} + {% set metadata = hookable_metadata.context.metadata %} + + {% set singularName = hookable_metadata.configuration.resource_name|default(metadata.applicationName ~ '.ui.' ~ _context.metadata.name) %} + {% set header = hookable_metadata.configuration.header|default(null) %} +{% else %} + {% set singularName = hookable_metadata.configuration.resource_name %} + {% set header = hookable_metadata.configuration.header %} +{% endif %} + +
+
+ {{ _header.h1(header is not null ? header|trans : 'sylius.ui.new'|trans ~ ' ' ~ singularName|trans) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index.html.twig new file mode 100644 index 0000000000..bb5fae5492 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index.html.twig @@ -0,0 +1,23 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% set prefixes = [ + 'sylius_admin.%resource_name%'|replace({'%resource_name%': resource_name|default(metadata.name)}), + 'sylius_admin.common' +] %} +{% set header = metadata.applicationName ~ '.ui.' ~ metadata.pluralName %} + +{% block title %}{{ header|trans }} | {{ parent() }}{% endblock %} + +{% block body %} + {% hook 'index' with { _prefixes: prefixes, metadata, resources } %} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {% hook 'index#stylesheets' with { _prefixes: prefixes } %} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + {% hook 'index#javascripts' with { _prefixes: prefixes } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid.html.twig new file mode 100644 index 0000000000..9672fdf4ae --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid.html.twig @@ -0,0 +1,5 @@ +
+
+ {% hook 'grid' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/data_table.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/data_table.html.twig new file mode 100644 index 0000000000..e8ce6b3057 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/data_table.html.twig @@ -0,0 +1,47 @@ +{% import '@SyliusAdmin/shared/helper/table.html.twig' as _table %} +{% import '@SyliusAdmin/shared/helper/pagination.html.twig' as _pagination %} + +{% set resources = hookable_metadata.context.resources %} +{% set data = resources.data %} +{% set definition = resources.definition %} + +{% if data|length > 0 %} +
+
+
+ {% if data|length > 0 and definition.actionGroups.bulk is defined and definition.getEnabledActions('bulk')|length > 0 %} +
+ {% for action in definition.getEnabledActions('bulk') %} + {{ sylius_grid_render_bulk_action(resources, action, null) }} + {% endfor %} +
+ {% endif %} +
+ {{ _pagination.numberOfResultsSelector(data, definition.limits) }} +
+
+
+
+ + + + {{ _table.headers(resources, resources.definition, app.request.attributes) }} + + + + {% for row in resources.data %} + {{ _table.row(resources, resources.definition, row) }} + {% endfor %} + +
+
+ +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/filters.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/filters.html.twig new file mode 100644 index 0000000000..5a9c6db323 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/filters.html.twig @@ -0,0 +1,33 @@ +{% import "@SyliusAdmin/shared/helper/accordion.html.twig" as _accordion %} +{% import "@SyliusAdmin/shared/helper/button.html.twig" as _button %} + +{% set resources = hookable_metadata.context.resources %} + +{% set path = path(app.request.attributes.get('_route'), app.request.attributes.all('_route_params')) %} +{% set areCriteriaSet = app.request.query.has('criteria') %} + +
+ {% set content %} +
+
+
+ {% for filter in resources.definition.enabledFilters|filter(filter => filter.enabled)|sort_by('position') %} +
+ {{ sylius_grid_render_filter(resources, filter) }} +
+ {% endfor %} +
+
+ {{ _button.primary({ text: 'sylius.ui.filter'|trans, icon: 'adjustments', type: 'submit', attr: sylius_test_html_attribute('filter') }) }} + {{ _button.default({ text: 'sylius.ui.reset'|trans, url: path, attr: sylius_test_html_attribute('reset') }) }} +
+
+
+ {% endset %} + + {{ _accordion.default([{ + title: 'sylius.ui.filters'|trans, + content: content, + icon: 'adjustments', + }], areCriteriaSet) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results.html.twig new file mode 100644 index 0000000000..3214bcafda --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results.html.twig @@ -0,0 +1,9 @@ +{% set resources = hookable_metadata.context.resources %} + +{% if resources.data|length == 0 %} +
+
+ {% hook 'no_results' %} +
+
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/action.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/action.html.twig new file mode 100644 index 0000000000..5fc4fdaa7c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/action.html.twig @@ -0,0 +1,10 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% if _context.route is defined and (_context.hidden is not defined or _context.hidden == false) %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/image.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/image.html.twig new file mode 100644 index 0000000000..a7c3a3de0a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/image.html.twig @@ -0,0 +1,5 @@ +{% if _context.hidden is not defined or _context.hidden == false %} +
+ +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/subtitle.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/subtitle.html.twig new file mode 100644 index 0000000000..25e5c100a2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/subtitle.html.twig @@ -0,0 +1,5 @@ +{% if _context.hidden is not defined or _context.hidden == false %} +

+ {{ _context.translation_key|default('sylius.ui.no_results_adjust_your_search')|trans }} +

+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/title.html.twig new file mode 100644 index 0000000000..bbf86cf339 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/grid/no_results/title.html.twig @@ -0,0 +1,3 @@ +{% if _context.hidden is not defined or _context.hidden == false %} +

{{ _context.translation_key|default('sylius.ui.no_results')|trans }}

+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..21393e4fd9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/index/content/header/breadcrumbs.html.twig @@ -0,0 +1,15 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set title_from_context = hookable_metadata.context.title|default(null) %} +{% set resource_metadata = hookable_metadata.context.metadata|default(null) %} + +{% if title_from_context is not null or resource_metadata is not null %} + {% set title = title_from_context|default(resource_metadata.applicationName~'.ui.'~resource_metadata.pluralName) %} +{% else %} + {% set title = hookable_metadata.configuration.title %} +{% endif %} + +{{ _breadcrumbs.default([ + { 'name': 'Dashboard', 'url': path('sylius_admin_dashboard'), 'active': false }, + { 'name': title, 'active': true }, +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show.html.twig new file mode 100644 index 0000000000..db290fc9a9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show.html.twig @@ -0,0 +1,24 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% set prefixes = [ + 'sylius_admin.%resource_name%'|replace({'%resource_name%': resource_name|default(metadata.name)}), + 'sylius_admin.common' +] %} + +{% set header = metadata.applicationName ~ '.ui.' ~ metadata.pluralName %} + +{% block title %}{{ header|trans }} | {{ parent() }}{% endblock %} + +{% block body %} + {% hook 'show' with { _prefixes: prefixes, resource, metadata, configuration } %} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {% hook 'show#stylesheets' with { _prefixes: prefixes } %} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + {% hook 'show#javascripts' with { _prefixes: prefixes } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..453706df90 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show/content/header/breadcrumbs.html.twig @@ -0,0 +1,24 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set configuration = hookable_metadata.context.configuration %} +{% set resource = hookable_metadata.context.resource %} + +{% if hookable_metadata.context.metadata is defined %} + {% set metadata = hookable_metadata.context.metadata %} + {% set resourceName = hookable_metadata.configuration.resource_name|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} +{% else %} + {% set resourceName = hookable_metadata.configuration.resource_name %} +{% endif %} + +{% set index_url = path( + configuration.vars.index.route.name|default(configuration.getRouteName('index')), + configuration.vars.index.route.parameters|default(configuration.vars.route.parameters|default({})) +) +%} + +{{ _breadcrumbs.default([ + { name: 'Dashboard', url: path('sylius_admin_dashboard'), active: false }, + { name: metadata.applicationName~'.ui.'~metadata.pluralName, url: index_url, active: false }, + { name: resource.name|default(resource.code|default(resource.id)), active: true }, + { name: 'sylius.ui.show'|trans, active: false } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..0da4dc5c76 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/show/content/header/title_block/title.html.twig @@ -0,0 +1,18 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +{% if hookable_metadata.context.metadata is defined and hookable_metadata.context.configuration is defined %} + {% set configuration = hookable_metadata.context.configuration %} + {% set metadata = hookable_metadata.context.metadata %} + + {% set singularName = hookable_metadata.configuration.resource_name|default(metadata.applicationName ~ '.ui.' ~ _context.metadata.name) %} + {% set header = hookable_metadata.configuration.header|default(null) %} +{% else %} + {% set singularName = hookable_metadata.configuration.resource_name %} + {% set header = hookable_metadata.configuration.header %} +{% endif %} + +
+
+ {{ _header.h1(header is not null ? header|trans : 'sylius.ui.show'|trans ~ ' ' ~ singularName|trans) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update.html.twig new file mode 100644 index 0000000000..ab13629baa --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update.html.twig @@ -0,0 +1,24 @@ +{% extends '@SyliusAdmin/shared/layout/base.html.twig' %} + +{% set prefixes = [ + 'sylius_admin.%resource_name%'|replace({'%resource_name%': resource_name|default(metadata.name)}), + 'sylius_admin.common' +] %} + +{% set header = metadata.applicationName ~ '.ui.' ~ metadata.pluralName %} + +{% block title %}{{ header|trans }} | {{ parent() }}{% endblock %} + +{% block body %} + {% hook 'update' with { _prefixes: prefixes, resource, metadata, configuration, form } %} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {% hook 'update#stylesheets' with { _prefixes: prefixes } %} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + {% hook 'update#javascripts' with { _prefixes: prefixes } %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/form.html.twig new file mode 100644 index 0000000000..f38cff30df --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/form.html.twig @@ -0,0 +1,47 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{% set resource = hookable_metadata.context.resource %} +{% set configuration = hookable_metadata.context.configuration %} +{% set form = hookable_metadata.context.form %} + +{% set route = configuration.vars.route|default(null) %} +{% set indexRoute = configuration.vars.index.route|default(null) %} +{% set index_url = path( + indexRoute.name|default(_context.configuration.getRouteName('index')), + indexRoute.parameters|default(route.parameters|default({})) +) %} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+
+ {% block content %} + {% set renderRest = hookable_metadata.configuration.render_rest %} + + {% if renderRest %} +
+
+ {% endif %} + {{ form_start(form, {'action': path(configuration.vars.route.name|default(configuration.getRouteName('update')), configuration.vars.route.parameters|default({ 'id': resource.id })), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% block form_content %} + + + {% hook 'form' with { form } %} + {% endblock %} + {{ form_end(form, {'render_rest': renderRest}) }} + {% if renderRest %} +
+ +
+ {% endif %} + {% endblock %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/breadcrumbs.html.twig new file mode 100644 index 0000000000..27fc3f1705 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/breadcrumbs.html.twig @@ -0,0 +1,25 @@ +{% import '@SyliusAdmin/shared/helper/breadcrumbs.html.twig' as _breadcrumbs %} + +{% set configuration = hookable_metadata.context.configuration %} +{% set resource = hookable_metadata.context.resource %} + + +{% if hookable_metadata.context.metadata is defined %} + {% set metadata = hookable_metadata.context.metadata %} + {% set resourceName = hookable_metadata.configuration.resource_name|default(metadata.applicationName~'.ui.'~metadata.pluralName) %} +{% else %} + {% set resourceName = hookable_metadata.configuration.resource_name %} +{% endif %} + +{% set index_url = path( + configuration.vars.index.route.name|default(configuration.getRouteName('index')), + configuration.vars.index.route.parameters|default(configuration.vars.route.parameters|default({})) +) +%} + +{{ _breadcrumbs.default([ + { name: 'Dashboard', url: path('sylius_admin_dashboard'), active: false }, + { name: resourceName, url: index_url, active: false }, + { name: resource.name|default(resource.code|default(resource.id)), active: true }, + { name: 'sylius.ui.edit'|trans, active: false } +]) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/title_block/actions.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/title_block/actions.html.twig new file mode 100644 index 0000000000..5b85ba8cb2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/title_block/actions.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +
+
+ {% hook 'actions' %} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/title_block/title.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/title_block/title.html.twig new file mode 100644 index 0000000000..fac63bfe5f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/crud/update/content/header/title_block/title.html.twig @@ -0,0 +1,18 @@ +{% import '@SyliusAdmin/shared/helper/header.html.twig' as _header %} + +{% if hookable_metadata.context.metadata is defined and hookable_metadata.context.configuration is defined %} + {% set configuration = hookable_metadata.context.configuration %} + {% set metadata = hookable_metadata.context.metadata %} + + {% set singularName = hookable_metadata.configuration.resource_name|default(metadata.applicationName ~ '.ui.' ~ _context.metadata.name) %} + {% set header = hookable_metadata.configuration.header|default(null) %} +{% else %} + {% set singularName = hookable_metadata.configuration.resource_name %} + {% set header = hookable_metadata.configuration.header %} +{% endif %} + +
+
+ {{ _header.h1(header is not null ? header|trans : 'sylius.ui.edit'|trans ~ ' ' ~ singularName|trans) }} +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/form_theme.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/form_theme.html.twig new file mode 100644 index 0000000000..11c323e36d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/form_theme.html.twig @@ -0,0 +1,82 @@ +{% extends 'bootstrap_5_layout.html.twig' %} + +{%- block form_start -%} + {%- do form.setMethodRendered() -%} + {% set method = method|upper %} + {%- if method in ["GET", "POST"] -%} + {% set form_method = method %} + {%- else -%} + {% set form_method = "POST" %} + {%- endif -%} + + {%- if form_method != method -%} + + {%- endif -%} +{%- endblock form_start -%} + +{%- block form_row -%} + {% set row_attr = row_attr|default({})|merge({ class: (row_attr.class|default('mb-3') ~ ' field')|trim }) %} + {{ parent() }} +{%- endblock form_row %} + +{% block sylius_resource_autocomplete_choice_row %} +
+ {{- form_label(form) -}} + + {{ form_widget(form) }} + {{- form_errors(form) -}} +
+{% endblock %} + +{% block sylius_channel_collection_row %} + +
+ +
+
+
+ {% for channelCode, channelConfiguration in form %} +
+ {{ form_row(channelConfiguration, sylius_test_form_attribute('tab-content')|merge({'label': false})) }} +
+ {% endfor %} +
+
+
+ {{ form_errors(form) }} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/create.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/create.html.twig new file mode 100644 index 0000000000..340e8ed683 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/create.html.twig @@ -0,0 +1,13 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('create')), options.link.parameters|default([]))) %} + +{% set message = action.label %} +{% if message is empty %} + {% set message = 'sylius.ui.create' %} +{% endif %} + + + {{ icon({ icon: action.icon ?? 'plus', class: 'icon icon-tabler dropdown-item-icon' }) }} + {{ message|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/default.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/default.html.twig new file mode 100644 index 0000000000..340e8ed683 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/default.html.twig @@ -0,0 +1,13 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('create')), options.link.parameters|default([]))) %} + +{% set message = action.label %} +{% if message is empty %} + {% set message = 'sylius.ui.create' %} +{% endif %} + + + {{ icon({ icon: action.icon ?? 'plus', class: 'icon icon-tabler dropdown-item-icon' }) }} + {{ message|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/link.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/link.html.twig new file mode 100644 index 0000000000..9d896c5b07 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/link.html.twig @@ -0,0 +1,3 @@ +{% set path = link.url is defined ? link.url : path(link.route, link.parameters|default([])) %} + +{% if link.icon is defined %} {% endif %}{{ link.label|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/links.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/links.html.twig new file mode 100644 index 0000000000..74c32ee377 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/links.html.twig @@ -0,0 +1,35 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set visible = options.visible is defined ? options.visible : true %} + +{% if visible %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/list.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/list.html.twig new file mode 100644 index 0000000000..8bf509d9cc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/action/list.html.twig @@ -0,0 +1,25 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set visible = options.visible is defined ? options.visible : true %} + +{% if visible %} +
+ {% if action.label %} + {{ action.label|trans }} + {% endif %} + + {% for link in options.links %} + {% set is_link_visible = link.visible is defined ? link.visible : true %} + + {% if is_link_visible %} + {% set path = link.url is defined ? link.url : path(link.route, link.parameters|default([])) %} + + {% if link.icon is defined %} + {{ icon({ icon: link.icon, class: 'icon icon-tabler dropdown-item-icon' }) }} + {% endif %} + {{ link.label|trans }} + + {% endif %} + {% endfor %} +
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/bulk_action/delete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/bulk_action/delete.html.twig new file mode 100644 index 0000000000..f6d72b8f0a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/bulk_action/delete.html.twig @@ -0,0 +1,15 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('bulk_delete')), options.link.parameters|default({}))) %} + +
+ + + {{ _button.delete({ + text: action.label|default('sylius.ui.delete')|trans, + disabled: true, + type: 'submit', + icon: 'trash-x', + attr: 'data-check-all-action=index data-confirm-btn-submit' + }) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/boolean.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/boolean.html.twig new file mode 100644 index 0000000000..1384dedbf8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/boolean.html.twig @@ -0,0 +1,7 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +{% if true == data %} +
{{ _icon({ icon: 'check', class: 'icon text-green' }) }}
+{% else %} +
{{ _icon({ icon: 'x', class: 'icon icon-sm text-secondary' }) }}
+{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/channel.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/channel.html.twig new file mode 100644 index 0000000000..7046320486 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/channel.html.twig @@ -0,0 +1,4 @@ + + + {{ data.name|default(data.code) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/channels.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/channels.html.twig new file mode 100644 index 0000000000..948e8f6602 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/channels.html.twig @@ -0,0 +1,5 @@ +
+ {% for channel in data %} +
{% include('@SyliusAdmin/shared/grid/field/channel.html.twig') with { data: channel } %}
+ {% endfor %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/code.html.twig new file mode 100644 index 0000000000..40a3aa6e85 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/code.html.twig @@ -0,0 +1,3 @@ +{% if data is not null %} + {{ data }} +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/customer.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/customer.html.twig similarity index 50% rename from src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/customer.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/customer.html.twig index f72f46f7a8..ac45be1eae 100644 --- a/src/Sylius/Bundle/AdminBundle/Resources/views/Order/Grid/Field/customer.html.twig +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/customer.html.twig @@ -1,2 +1,2 @@ {{ data.firstName }} {{ data.lastName }} -

{{ data.email }}

+
{{ data.email }}
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/date.html.twig new file mode 100644 index 0000000000..c5b6482786 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/date.html.twig @@ -0,0 +1,8 @@ +
+ {% if data is null %} + - + {% else %} +
{{ data|date('d-m-Y') }}
+
{{ data|date('H:i:s') }}
+ {% endif %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/label.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/label.html.twig new file mode 100644 index 0000000000..d207a1d867 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/label.html.twig @@ -0,0 +1 @@ +{{ data|capitalize }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/name.html.twig new file mode 100644 index 0000000000..63cd1c27b5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/name.html.twig @@ -0,0 +1,3 @@ +{% if data is not null %} + {{ data }} +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/order_number.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/order_number.html.twig new file mode 100644 index 0000000000..a808151a8a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/order_number.html.twig @@ -0,0 +1 @@ +#{{ data.number }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/payment_state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/payment_state.html.twig new file mode 100644 index 0000000000..fff62c1dd9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/payment_state.html.twig @@ -0,0 +1,18 @@ +{% + set viewOptions = { + authorized: { color: 'bg-orange-lt' }, + cancelled: { color: 'bg-yellow-lt' }, + cart: { color: 'bg-lime-lt' }, + completed: { color: 'bg-green-lt' }, + failed: { color: 'bg-red-lt' }, + new: { color: '' }, + processing: { color: 'bg-indigo-lt' }, + refunded: { color: 'bg-purple-lt' }, +} +%} + +{% set value = 'sylius.ui.' ~ data %} + + + {{ value|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/shipment_state.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/shipment_state.html.twig new file mode 100644 index 0000000000..eaea25b150 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/field/shipment_state.html.twig @@ -0,0 +1,14 @@ +{% + set viewOptions = { + cancelled: { color: 'bg-red-lt' }, + cart: { color: '' }, + ready: { color: 'bg-blue-lt' }, + shipped: { color: 'bg-green-lt' }, +} +%} + +{% set value = 'sylius.ui.' ~ data %} + + + {{ value|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/autocomplete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/autocomplete.html.twig new file mode 100644 index 0000000000..9f591997ea --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/autocomplete.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/boolean.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/boolean.html.twig new file mode 100644 index 0000000000..4596454549 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/boolean.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/date.html.twig new file mode 100644 index 0000000000..b45d722388 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/date.html.twig @@ -0,0 +1,6 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_row(form.from, { attr: {'class': 'input-group'}, 'label': 'sylius.ui.date_filter', 'label_translation_parameters': {'%label%': filter.label|trans, '%altLabel%': form.from.vars.label|trans} }) }} + {{ form_row(form.to, { attr: {'class': 'input-group'} }) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/entities.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/entities.html.twig new file mode 100644 index 0000000000..4596454549 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/entities.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/entity.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/entity.html.twig new file mode 100644 index 0000000000..4596454549 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/entity.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/exists.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/exists.html.twig new file mode 100644 index 0000000000..4596454549 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/exists.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/money.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/money.html.twig new file mode 100644 index 0000000000..97ada8556c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/money.html.twig @@ -0,0 +1,7 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {{ form_row(form.greaterThan, {attr: {'placeholder': form.greaterThan.vars.label}, 'label': 'sylius.ui.money_filter', 'label_translation_parameters': {'%label%': filter.label|trans, '%altLabel%': form.greaterThan.vars.label|trans}}) }} + {{ form_row(form.lessThan, {attr: { 'placeholder': form.lessThan.vars.label }}) }} + {{ form_row(form.currency) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/resource_autocomplete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/resource_autocomplete.html.twig new file mode 100644 index 0000000000..43154a18b4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/resource_autocomplete.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form, {'label': filter.label, 'remote_url': path(filter.formOptions.remote_path), 'load_edit_url': path(filter.formOptions.load_edit_path)}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/select.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/select.html.twig new file mode 100644 index 0000000000..4596454549 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/select.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/string.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/string.html.twig new file mode 100644 index 0000000000..d4163861ae --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/filter/string.html.twig @@ -0,0 +1,8 @@ +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
+ {% if form.type is defined %} + {{ form_row(form.type, {'label': filter.label}) }} + {% endif %} + {{ form_row(form.value, {attr: {placeholder: form.value.vars.label}, 'label': form.type is defined ? form.value.vars.label : filter.label}) }} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/apply_transition.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/apply_transition.html.twig new file mode 100644 index 0000000000..ea5d4d5c42 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/apply_transition.html.twig @@ -0,0 +1,19 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set labeled = options.labeled is defined ? options.labeled : true %} + +{% if sylius_sm_can(data, options.graph, options.transition) %} +
+ + + +
+{% else %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/archive.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/archive.html.twig new file mode 100644 index 0000000000..c80ebb9242 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/archive.html.twig @@ -0,0 +1,20 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('archive')), options.link.parameters|default({'id': data.id}))) %} +{% set message = action.label|default('sylius.ui.delete') %} + +
+ + + + {% if data.archivedAt is not null %} + + {% else %} + + {% endif %} +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/create.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/create.html.twig new file mode 100644 index 0000000000..340e8ed683 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/create.html.twig @@ -0,0 +1,13 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('create')), options.link.parameters|default([]))) %} + +{% set message = action.label %} +{% if message is empty %} + {% set message = 'sylius.ui.create' %} +{% endif %} + + + {{ icon({ icon: action.icon ?? 'plus', class: 'icon icon-tabler dropdown-item-icon' }) }} + {{ message|trans }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/default.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/default.html.twig new file mode 100644 index 0000000000..b0d1005b07 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/default.html.twig @@ -0,0 +1,7 @@ +{% set path = options.link.url|default(path(options.link.route, options.link.parameters|default({}))) %} + +{% set message = action.label %} + + + {% if message %}{{ message|trans }}{% endif %} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/delete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/delete.html.twig new file mode 100644 index 0000000000..81ffb097bf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/delete.html.twig @@ -0,0 +1,12 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('delete')), options.link.parameters|default({'id': data.id}))) %} +{% set message = action.label|default('sylius.ui.delete') %} + +
+ + + +
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/link.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/link.html.twig new file mode 100644 index 0000000000..d094f2da1c --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/link.html.twig @@ -0,0 +1,3 @@ +{% set path = link.url is defined ? link.url : path(link.route, link.parameters|default([])) %} + +{% if link.icon is defined %} {% endif %}{{ link.label|trans }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/links.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/links.html.twig new file mode 100644 index 0000000000..e8b7e6bab5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/links.html.twig @@ -0,0 +1,24 @@ +{% set visible = options.visible is defined ? options.visible : true %} + +{% if visible %} + +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/show.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/show.html.twig new file mode 100644 index 0000000000..2ba90e1c6e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/show.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('show')), options.link.parameters|default({'id': data.id}))) %} +{% set message = action.label|default('sylius.ui.show') %} + + + {{ icon({ icon: action.icon|default('eye'), class: 'icon icon-tabler' }) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/update.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/update.html.twig new file mode 100644 index 0000000000..6d65cb721e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/grid/item_action/update.html.twig @@ -0,0 +1,8 @@ +{% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('update')), options.link.parameters|default({'id': data.id}))) %} +{% set message = action.label|default('sylius.ui.edit') %} + + + {{ icon({ icon: action.icon|default('pencil'), class: 'icon icon-tabler' }) }} + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/accordion.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/accordion.html.twig new file mode 100644 index 0000000000..840c3965ac --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/accordion.html.twig @@ -0,0 +1,47 @@ +{% macro default(items, open = false, autoClose = null, flush = false) %} + {% from "@SyliusAdmin/shared/helper/icon.html.twig" import icon %} + + {% set autoClose = autoClose|default(true) %} + {% set id = id|default(random()) %} + +
+ {% for item in items %} + {% set item = { + 'open': open, + 'flag': null, + 'icon': null, + }|merge(item) %} + {% set item_id = item.id|default('collapse' ~ loop.index) %} + +
+

+ +

+
+ +
+ {{ item.content|default('Content') }} +
+
+
+ {% endfor %} +
+{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/address.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/address.html.twig new file mode 100644 index 0000000000..71dea4c29a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/address.html.twig @@ -0,0 +1,15 @@ +{% macro default(address) %} +
+ {{ address.firstName }} {{ address.lastName }} + {% if address.company %} + {{ address.company }}
+ {% endif %} + {{ address.phoneNumber }}
+ {{ address.street }}
+ {{ address.city }}
+ {% if address|sylius_province_name is not empty %} + {{ address|sylius_province_name }}
+ {% endif %} + {{ address.countryCode|sylius_country_name|upper }} {{ address.postcode }} +
+{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/avatar.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/avatar.html.twig new file mode 100644 index 0000000000..3b902f9a38 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/avatar.html.twig @@ -0,0 +1,16 @@ +{% macro default(img, content, class) %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + + + {% if content %} + {{ content }} + {% else %} + {{ icon({ icon: 'user' }) }} + {% endif %} + +{% endmacro %} + +{% macro small(img, content, class) %} + {% import _self as _ %} + {{ _.default(img, content, 'avatar-sm ' ~ class) }} +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/breadcrumbs.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/breadcrumbs.html.twig new file mode 100644 index 0000000000..a98b746ed7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/breadcrumbs.html.twig @@ -0,0 +1,13 @@ +{% macro default(breadcrumbs) %} + +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/button.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/button.html.twig new file mode 100644 index 0000000000..5816f983e7 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/button.html.twig @@ -0,0 +1,110 @@ +{% macro default(params = {}) %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as i %} + + {% set p = { + attr: null, + class: null, + text: "Button", + disabled: false, + dropdown: false, + icon: null, + iconOnly: false, + id: null, + size: null, + type: "button", + url: null, + form: null, + }|merge(params) %} + + {% set buttonClass = 'btn' ~ + (p.class ? ' ' ~ p.class : '') ~ + (p.dropdown ? ' dropdown-toggle' : '') ~ + (p.iconOnly ? ' btn-icon' : '') ~ + (p.size == 'large' ? ' btn-lg' : '') ~ + (p.size == 'small' ? ' btn-sm' : '') %} + + {% if p.url %} + + {{ p.icon ? i({ icon: p.icon }) }} + {{ not p.iconOnly ? p.text }} + + {% else %} + + {% endif %} +{% endmacro %} + +{% macro primary(params = {}) %} + {% import _self as _ %} + {% set params = { + class: null, + }|merge(params) %} + + {% set newParams = params|merge({ class: 'btn-primary ' ~ params.class }) %} + {{ _.default(newParams) }} +{% endmacro %} + +{% macro delete(params = {}) %} + {% import _self as _ %} + {% set params = { + class: null, + }|merge(params) %} + + {% set newParams = { text: 'Delete' }|merge(params)|merge({ class: 'btn btn-ghost-danger ' ~ params.class }) %} + {{ _.default(newParams) }} +{% endmacro %} + +{% macro create(params = {}) %} + {% import _self as _ %} + {% set params = { + type: 'submit', + text: 'sylius.ui.create'|trans, + }|merge(params) %} + + {{ _.primary(params) }} +{% endmacro %} + +{% macro update(params = {}) %} + {% import _self as _ %} + {% set params = { + type: 'submit', + text: 'sylius.ui.save_changes'|trans, + }|merge(params) %} + + {{ _.primary(params) }} +{% endmacro %} + +{% macro cancel(params = {}) %} + {% import _self as _ %} + {% set params = { + class: null, + text: 'sylius.ui.cancel'|trans, + url: app.request.headers.get('referer'), + }|merge(params)%} + + {{ _.default(params) }} +{% endmacro %} + +{% block attributes -%} + {%- for attrname, attrvalue in p.attr -%} + {{- " " -}} + {%- if attrvalue is same as(true) -%} + {{- attrname }}="{{ attrname }}" + {%- elseif attrvalue is not same as(false) -%} + {{- attrname }}="{{ attrvalue }}" + {%- endif -%} + {%- endfor -%} +{%- endblock attributes -%} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/channelPricings.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/channelPricings.html.twig new file mode 100644 index 0000000000..46e4c0c65f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/channelPricings.html.twig @@ -0,0 +1,36 @@ +{% macro default(channelPricingForms, product_variant, body = null, options = {}) %} + {% set options = { + accordionId: 'product-channel-pricings' + }|merge(options) %} + +
+ {% for channelCode, channelPricingForm in channelPricingForms %} +
+

+ +

+
+
+ {% if body is not null %} + {{ include(template_from_string(body), { channelCode: channelCode, channelPricingForm: channelPricingForm, product_variant: product_variant}) }} + {% else %} + {% for field in channelPricingForm %} + {{ form_row(field) }} + {% endfor %} + {% endif %} +
+
+
+ {% endfor %} +
+{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/dropdown.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/dropdown.html.twig new file mode 100644 index 0000000000..ea874e9ed0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/dropdown.html.twig @@ -0,0 +1,55 @@ +{% macro default(params) %} + {% import '@SyliusAdmin/shared/helper/button.html.twig' as button %} + {% set p = { + button: {}, + class: null, + content: null, + customTrigger: null, + direction: 'down' + }|merge(params) %} + + {% if p.direction == 'down' %}{% set drop = '' %}{% endif %} + {% if p.direction == 'down-end' %}{% set drop = ' dropdown-menu-end' %}{% endif %} + + +{% endmacro %} + +{% macro list(params, items) %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + {% import _self as _ %} + + {% set content %} + {% for item in items %} + {% set item = { + type: null, + class: null, + icon: null + }|merge(item) %} + + {% if item.type == 'header' %} + {{ item.title }} + {% elseif item.type == 'divider' %} + + {% else %} + {% set extra_class = item.class ? ' ' ~ item.class %} + + {{ item.icon ? icon({ icon: item.icon, class: 'icon dropdown-item-icon icon-tabler' ~ extra_class }) }} + {{ item.title }} + + {% endif %} + {% endfor %} + {% endset %} + + {% set newParams = params|merge({ content: content }) %} + {{ _.default(newParams) }} +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/header.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/header.html.twig new file mode 100644 index 0000000000..f3d9e5f669 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/header.html.twig @@ -0,0 +1,17 @@ +{% macro default(level, header, icon, subheader) %} + + {# TODO: Decide whether we want to have an image here #} + {# {% if icon is not empty %}#} + {# #} + {# {% endif %}#} + {{ header }} + {% if subheader is not empty %} + {# TODO: Fix subheader styling #} + {# {{ subheader }}#} + {% endif %} + +{% endmacro %} + +{% macro h1(header, icon, subheader) %} + {{ _self.default(1, header, icon, subheader) }} +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/icon.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/icon.html.twig new file mode 100644 index 0000000000..959980fff0 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/icon.html.twig @@ -0,0 +1,336 @@ +{% macro icon(params) %} + {% set icon = params.icon %} + {% set class = params.class|default('icon icon-tabler') %} + {% set width = params.width|default(24) %} + {% set height = params.height|default(24) %} + {% set stroke = params.stroke|default(2) %} + {% set strokeColor = params.strokeColor|default('currentColor') %} + {% set fill = params.fill|default('none') %} + + + {% if icon == 'search' %} + + + + {% endif %} + + {% if icon == 'bell' %} + + + + {% endif %} + + {% if icon == 'dashboard' %} + + + + + {% endif %} + + {% if icon == 'list-details' %} + + + + + + + + {% endif %} + + {% if icon == 'shopping-bag' %} + + + + {% endif %} + + {% if icon == 'user' %} + + + + {% endif %} + + {% if icon == 'users' %} + + + + + + {% endif %} + + {% if icon == 'percentage' %} + + + + + {% endif %} + + {% if icon == 'payment' %} + + + + + + {% endif %} + + {% if icon == 'adjustments' %} + + + + + + + + + + + {% endif %} + + {% if icon == 'plus' %} + + + + {% endif %} + + {% if icon == 'chevron-up' %} + + + {% endif %} + + {% if icon == 'chevron-down' %} + + + {% endif %} + + {% if icon == 'chevron-left' %} + + + {% endif %} + + {% if icon == 'chevron-right' %} + + + {% endif %} + + {% if icon == 'pencil' %} + + + + {% endif %} + + {% if icon == 'eye' %} + + + + {% endif %} + + {% if icon == 'trash-x' %} + + + + + + {% endif %} + + {% if icon == 'arrow-up-right' %} + + + + {% endif %} + + {% if icon == 'circle-check' %} + + + + {% endif %} + + {% if icon == 'info-circle' %} + + + + + {% endif %} + + {% if icon == 'exclamation-circle' %} + + + + + {% endif %} + + {% if icon == 'check' %} + + + {% endif %} + + {% if icon == 'x' %} + + + + {% endif %} + + {% if icon == 'history' %} + + + + {% endif %} + + {% if icon == 'send' %} + + + + {% endif %} + + {% if icon == 'spy' %} + + + + + + + {% endif %} + + {% if icon == 'coins' %} + + + + + + + {% endif %} + + {% if icon == 'slash' %} + + + {% endif %} + + {% if icon == 'external-link' %} + + + + + {% endif %} + + {% if icon == 'logout' %} + + + + + {% endif %} + + {% if icon == 'selector' %} + + + + {% endif %} + + {% if icon == 'danger' %} + + + + + {% endif %} + + {% if icon == 'warning' %} + + + + {% endif %} + + {% if icon == 'info' %} + + + + + {% endif %} + + {% if icon == 'success' %} + + + {% endif %} + + {% if icon == 'world' %} + + + + + + + {% endif %} + + {% if icon == 'cube' %} + + + + + + {% endif %} + + {% if icon == 'arrows-shuffle' %} + + + + + + {% endif %} + + {% if icon == 'arrows-split' %} + + + + + + {% endif %} + + {% if icon == 'history' %} + + + + {% endif %} + + {% if icon == 'arrow-back-up' %} + + + + {% endif %} + + {% if icon == 'arrow-back-up-double' %} + + + + + {% endif %} + + {% if icon == 'archive' %} + + + + + {% endif %} + + {% if icon == 'list-letters' %} + + + + + + + + {% endif %} + + {% if icon == 'dots' %} + + + + + {% endif %} + +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/Resources/views/Common/Macro/money.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/money.html.twig similarity index 100% rename from src/Sylius/Bundle/AdminBundle/Resources/views/Common/Macro/money.html.twig rename to src/Sylius/Bundle/AdminBundle/templates/shared/helper/money.html.twig diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/pagination.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/pagination.html.twig new file mode 100644 index 0000000000..df9e79a780 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/pagination.html.twig @@ -0,0 +1,25 @@ +{% macro simple(paginator) %} + {{ pagerfanta(paginator, 'twig', options|default({'template': '@SyliusAdmin/shared/pagerfanta.html.twig'})) }} +{% endmacro %} + +{% macro resultsCount(paginator) %} + {% set from = 1 + (paginator.currentPage - 1) * paginator.maxPerPage %} + {% set to = paginator.maxPerPage + (paginator.currentPage - 1) * paginator.maxPerPage %} + {% set to = to < paginator.nbResults ? to : paginator.nbResults %} + + {{ 'sylius.ui.pagination.number_of_results'|trans({'%from%': from, '%to%': to, '%total%': paginator.nbResults}) }} +{% endmacro %} + +{% macro numberOfResultsSelector(paginator, paginationLimits) %} + +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/product.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/product.html.twig new file mode 100644 index 0000000000..c15fe9b323 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/product.html.twig @@ -0,0 +1,11 @@ +{% macro image(product) %} + {% if product.imagesByType('thumbnail') is not empty %} + {% set path = product.imagesByType('thumbnail').first.path|imagine_filter(filter|default('sylius_shop_product_thumbnail')) %} + {% elseif product.images.first %} + {% set path = product.images.first.path|imagine_filter(filter|default('sylius_shop_product_thumbnail')) %} + {% else %} + {% set path = asset('build/shop/images/200x200.png', 'shop') %} + {% endif %} + + {{ product.name }} +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/sorting.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/sorting.html.twig new file mode 100644 index 0000000000..7284c28b19 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/sorting.html.twig @@ -0,0 +1,38 @@ +{% macro tableHeader(grid, field, attributes) %} + {% from _self import link %} + {% set order = grid.getSortingOrder(field.name) %} + + {% if grid.isSortedBy(field.name) %} + + + {{ field.label|trans }} + {% if order == 'desc' %} + + + + {% endif %} + {% if order == 'asc' %} + + + + {% endif %} + + + {% else %} + + + {{ field.label|trans }} + + + + + + {% endif %} +{% endmacro %} + +{% macro link(fieldName, attributes, order, parameters) %} + {% set params = attributes.all('_route_params')|merge(parameters) %} + {% set sorting = {'sorting': {(fieldName): (order)}} %} + + {{ path(attributes.get('_route'), params|merge(sorting)|merge({'page': 1})) }} +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/table.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/table.html.twig new file mode 100644 index 0000000000..331e024219 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/table.html.twig @@ -0,0 +1,63 @@ +{% macro headers(grid, definition, requestAttributes) %} + {% import '@SyliusAdmin/shared/helper/sorting.html.twig' as sorting %} + + {% if definition.actionGroups.bulk is defined and definition.getEnabledActions('bulk')|length > 0 %} + + + + {% endif %} + + {% for field in definition.fields|sort_by('position') %} + {% if field.enabled %} + {% if field.isSortable %} + {{ sorting.tableHeader(grid, field, requestAttributes) }} + {% else %} + {{ field.label|trans }} + {% endif %} + {% endif %} + {% endfor %} + {% if definition.actionGroups.item is defined and definition.getEnabledActions('item')|length > 0 %} + {{ 'sylius.ui.actions'|trans }} + {% endif %} +{% endmacro %} + +{% macro row(grid, definition, row) %} + {% from '@SyliusAdmin/shared/helper/dropdown.html.twig' import default as dropdown %} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon %} + + + {% if definition.actionGroups.bulk is defined and definition.getEnabledActions('bulk')|length > 0 %} + + {% endif %} + {% for field in definition.enabledFields|sort_by('position') %} + + {{ sylius_grid_render_field(grid, field, row) }} + + {% endfor %} + {% if definition.actionGroups.item is defined and definition.getEnabledActions('item')|length > 0 %} + +
+ {% for action in definition.getEnabledActions('item')|sort_by('position') %} + {{ sylius_grid_render_item_action(grid, action, row) }} + {% endfor %} + + {% if definition.actionGroups.subitem is defined and definition.getEnabledActions('subitem')|length > 0 %} + {% set subactions %} + {% for action in definition.getEnabledActions('subitem')|sort_by('position') %} + {{ sylius_grid_render_action(grid, action, row) }} + {% endfor %} + {% endset %} + {% set more_button %} + + {% endset %} + {% if subactions|trim|length > 0 %} + {{ dropdown({ customTrigger: more_button, content: subactions, direction: 'down-end' }) }} + {% endif %} + {% endif %} +
+ + {% endif %} + +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/helper/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/translations.html.twig new file mode 100644 index 0000000000..fcd125cbb2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/helper/translations.html.twig @@ -0,0 +1,58 @@ +{% macro default(translationFields, body = null, options = {}) %} + {% from _self import accordion_header %} + + {% set accordionId = options.accordionId|default('translations') %} +
+ {% for locale, translationForm in translationFields %} +
+ {{ accordion_header(locale, accordionId, loop.first) }} +
+
+ {% if body is not null %} + {{ include(template_from_string(body), { locale: locale, translationForm: translationForm }) }} + {% else %} + {% for field in translationForm %} + {{ form_row(field) }} + {% endfor %} + {% endif %} +
+
+
+ {% endfor %} +
+{% endmacro %} + +{% macro with_hook(translationFields, prefixes, hook_name = null, options = {}) %} + {% from _self import accordion_header %} + + {% set accordionId = options.accordionId|default('translations') %} +
+ {% for locale, translationForm in translationFields %} +
+ {{ accordion_header(locale, accordionId, loop.first) }} +
+
+ {% hook hook_name|default('translations') with { form: translationForm, _prefixes: prefixes } %} +
+
+
+ {% endfor %} +
+{% endmacro %} + +{% macro accordion_header(locale, accordionId, is_first = false) %} +

+ +

+{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/layout/base.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/layout/base.html.twig new file mode 100644 index 0000000000..13cb0195a6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/layout/base.html.twig @@ -0,0 +1,30 @@ +{% set generic_hook = 'sylius_admin.base' %} + + + + + + + + + {% block title %}Sylius{% endblock %} + + {% block metatags %}{% endblock %} + {{ encore_entry_link_tags('admin-entry', null, 'admin') }} + {% block stylesheets %} + {% hook generic_hook ~ '#stylesheets' %} + {% endblock %} + + +
+ {% block body %}{% endblock %} +
+ + {% include '@SyliusAdmin/shared/layout/dialog.html.twig' %} + + {{ encore_entry_script_tags('admin-entry', null, 'admin') }} + {% block javascripts %} + {% hook generic_hook ~ '#javascripts' %} + {% endblock %} + + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/layout/dialog.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/layout/dialog.html.twig new file mode 100644 index 0000000000..618b3b07ac --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/layout/dialog.html.twig @@ -0,0 +1,15 @@ +{% import '@SyliusAdmin/shared/helper/button.html.twig' as _button %} + + +
+
+
+ {{ 'sylius.ui.are_your_sure_you_want_to_perform_this_action'|trans }} +
+
+ +
+
diff --git a/src/Sylius/Bundle/AdminBundle/templates/shared/pagerfanta.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shared/pagerfanta.html.twig new file mode 100644 index 0000000000..ff72254977 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shared/pagerfanta.html.twig @@ -0,0 +1,59 @@ +{%- extends '@Pagerfanta/default.html.twig' -%} + +{%- block pager_widget -%} +
    + {{- block('pager') -}} +
+{%- endblock pager_widget -%} + +{%- block page_link -%} +
  • {{- page -}}
  • +{%- endblock page_link -%} + +{%- block current_page_link -%} +
  • {{- page -}}
  • +{%- endblock current_page_link -%} + +{%- block previous_page_link -%} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
  • + +
  • +{%- endblock previous_page_link -%} + +{%- block previous_page_link_disabled -%} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
  • + + {{ _icon({ icon: 'chevron-left' }) }} {{- block('previous_page_message') -}} + +
  • +{%- endblock previous_page_link_disabled -%} + +{%- block next_page_link -%} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
  • + +
  • +{%- endblock next_page_link -%} + +{%- block next_page_link_disabled -%} + {% from '@SyliusAdmin/shared/helper/icon.html.twig' import icon as _icon %} + +
  • + + {{- block('next_page_message') -}} {{ _icon({ icon: 'chevron-right' }) }} + +
  • +{%- endblock next_page_link_disabled -%} + +{%- block ellipsis -%} +
  • +{%- endblock ellipsis -%} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipment/component/ship.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipment/component/ship.html.twig new file mode 100644 index 0000000000..dac593666b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipment/component/ship.html.twig @@ -0,0 +1,16 @@ +{# Rendered with using \Sylius\Bundle\AdminBundle\TwigComponent\Shipment\ShipType #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +{% if sylius_sm_can(shipment, 'sylius_shipment', 'ship') %} +
    + {{ form_start(form, {'action': path('sylius_admin_shipment_ship', {id: shipment.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + +
    + {{ form_widget(form.tracking, sylius_test_form_attribute('shipment-tracking')|sylius_merge_recursive({'attr': {'placeholder': 'sylius.ui.tracking_code'|trans ~ '...'}})) }} + +
    + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
    +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipment/grid/action/ship_with_tracking_code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipment/grid/action/ship_with_tracking_code.html.twig new file mode 100644 index 0000000000..5d32a1fc23 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipment/grid/action/ship_with_tracking_code.html.twig @@ -0,0 +1,3 @@ + diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form.html.twig new file mode 100644 index 0000000000..c0be625b10 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form.html.twig @@ -0,0 +1,25 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\ShippingMethod\FormComponent #} + +{% form_theme form '@SyliusAdmin/shipping_method/form_theme.html.twig' %} + +
    + {{ form_start(form, {'attr': {'novalidate': 'novalidate', 'id': form.vars.id}}) }} +
    + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} +
    +
    +
    + {% hook 'form#left' with { form } %} +
    +
    + {% hook 'form#right' with { form } %} +
    +
    + {{ form_end(form, {render_rest: hookable_metadata.configuration.render_rest|default(false)}) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/availability.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/availability.html.twig new file mode 100644 index 0000000000..fd66d49aa8 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/availability.html.twig @@ -0,0 +1,7 @@ +
    +
    +
    + {% hook 'availability' %} +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/availability/channels.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/availability/channels.html.twig new file mode 100644 index 0000000000..a77eb3c33e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/availability/channels.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.channels) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements.html.twig new file mode 100644 index 0000000000..d4ffda5990 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements.html.twig @@ -0,0 +1,7 @@ +
    +
    +
    + {% hook 'category_requirements' %} +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements/category.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements/category.html.twig new file mode 100644 index 0000000000..f116ac2390 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements/category.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.category) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements/category_requirement.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements/category_requirement.html.twig new file mode 100644 index 0000000000..6f1a59eee4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/category_requirements/category_requirement.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.categoryRequirement, {'label': false}) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details.html.twig new file mode 100644 index 0000000000..87b43e09be --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details.html.twig @@ -0,0 +1,7 @@ +
    +
    +
    + {% hook 'details' %} +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/code.html.twig new file mode 100644 index 0000000000..f1bf35c945 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/code.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.code) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/enabled.html.twig new file mode 100644 index 0000000000..577ae83362 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/enabled.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.enabled) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/position.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/position.html.twig new file mode 100644 index 0000000000..186ab0ba33 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/position.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.position) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/zone.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/zone.html.twig new file mode 100644 index 0000000000..c2f70c9d52 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/details/zone.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.zone) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/rules.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/rules.html.twig new file mode 100644 index 0000000000..a3b3af7dd4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/rules.html.twig @@ -0,0 +1,22 @@ +
    +
    +
    +
    + {{ 'sylius.ui.rules'|trans }} +
    +
    +
    + +
    + {{ form_row(hookable_metadata.context.form.rules, {label: false}) }} +
    +
    + +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges.html.twig new file mode 100644 index 0000000000..b638b700bb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges.html.twig @@ -0,0 +1,7 @@ +
    +
    +
    + {% hook 'shipping_charges' %} +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges/calculator.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges/calculator.html.twig new file mode 100644 index 0000000000..e0d476168d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges/calculator.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.calculator) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges/configuration.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges/configuration.html.twig new file mode 100644 index 0000000000..b6b8baa92f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/shipping_charges/configuration.html.twig @@ -0,0 +1,16 @@ +{% set form = hookable_metadata.context.form %} + +{% if form.calculator.vars.value is not empty %} +
    + {% if form.configuration is defined %} + {{ form_row(form.configuration) }} + {% else %} + {% for name, calculatorConfigurationPrototype in form.vars.prototypes %} + {% set chosenCalculator = 'calculators_' ~ form.calculator.vars.value %} + {% if chosenCalculator == name %} + {{ form_row(calculatorConfigurationPrototype) }} + {% endif %} + {% endfor %} + {% endif %} +
    +{% endif %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/taxes.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/taxes.html.twig new file mode 100644 index 0000000000..36df24af89 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/taxes.html.twig @@ -0,0 +1,7 @@ +
    +
    +
    + {% hook 'taxes' %} +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/taxes/tax_category.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/taxes/tax_category.html.twig new file mode 100644 index 0000000000..06a25c10a4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/taxes/tax_category.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.taxCategory) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/translations.html.twig new file mode 100644 index 0000000000..2908ad9bbe --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form/translations.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +{% set form = hookable_metadata.context.form %} + +
    + {{ _translations.default(form.translations) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form_theme.html.twig b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form_theme.html.twig new file mode 100644 index 0000000000..60949b495a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/shipping_method/form_theme.html.twig @@ -0,0 +1,39 @@ +{% extends '@SyliusAdmin/shared/form_theme.html.twig' %} + +{%- block live_collection_widget -%} + {{ block('form_widget') }} +{%- endblock live_collection_widget -%} + +{%- block live_collection_entry_row -%} +
    + {{- form_errors(form) -}} + {{- form_row(form.type) -}} + +
    +
    +
    {{ (form.vars.types[form.type.vars.data])|trans }}
    + {{- form_row(button_delete, sylius_test_form_attribute('delete-action')|sylius_merge_recursive({'attr': {'class': 'btn-close'}})) -}} +
    +
    + {{- form_row(form.configuration, {'label': false}) -}} +
    +
    +
    +{%- endblock live_collection_entry_row -%} + +{% block add_button_row %} + {% if types is not empty %} + + {% endif %} +{% endblock %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections.html.twig new file mode 100644 index 0000000000..7a69be0dc6 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections.html.twig @@ -0,0 +1,5 @@ +
    + {% hook 'sections' %} + + {{ form_row(hookable_metadata.context.form._token) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration.html.twig new file mode 100644 index 0000000000..acc67893e5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration.html.twig @@ -0,0 +1,14 @@ +
    +
    +
    +
    + {{ 'sylius.ui.configuration'|trans }} +
    +
    +
    +
    + {% hook 'configuration' %} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/amount.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/amount.html.twig new file mode 100644 index 0000000000..dca9cb23fc --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/amount.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.amount) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/calculator.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/calculator.html.twig new file mode 100644 index 0000000000..ff5bf2d7a4 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/calculator.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.calculator) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/category.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/category.html.twig new file mode 100644 index 0000000000..782971bdbd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/category.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.category) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/end_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/end_date.html.twig new file mode 100644 index 0000000000..47acafb84f --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/end_date.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.endDate) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/included_in_price.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/included_in_price.html.twig new file mode 100644 index 0000000000..993c4f7e1e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/included_in_price.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.includedInPrice) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/start_date.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/start_date.html.twig new file mode 100644 index 0000000000..b476586584 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/start_date.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.startDate) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/zone.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/zone.html.twig new file mode 100644 index 0000000000..1762c62b2b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/configuration/zone.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.zone) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details.html.twig new file mode 100644 index 0000000000..26577d3b09 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details.html.twig @@ -0,0 +1,14 @@ +
    +
    +
    +
    + {{ 'sylius.ui.details'|trans }} +
    +
    +
    +
    + {% hook 'details' %} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details/code.html.twig new file mode 100644 index 0000000000..69861ccd02 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details/code.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.code) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details/name.html.twig new file mode 100644 index 0000000000..ff93f7b852 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/tax_rate/form/sections/details/name.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.name) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/helper/tree.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/helper/tree.html.twig new file mode 100644 index 0000000000..bd931c0519 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/helper/tree.html.twig @@ -0,0 +1,129 @@ +{% macro tree_dropdown(taxonId) %} + +{% endmacro %} + +{% macro tree_header(taxon) %} + {% import _self as _ %} + +
    +
    +
    + + + + + + + + + + + + + {{ taxon.name }} +
    +
    {{ _.tree_dropdown(taxon.id) }}
    +
    +
    +{% endmacro %} + +{% macro tree_link(taxon, url) %} + {% import _self as _ %} + +
    + + + + + + + + {{ taxon.name }} + +
    {{ _.tree_dropdown(taxon.id) }}
    +
    +{% endmacro %} + +{% macro render(taxons, nested = false) %} + {% import '@SyliusAdmin/taxon/helper/tree.html.twig' as _self %} + +
      + {% if nested == false %} +
      +
      + Loading +
      +
      + + {% endif %} + {% for taxon in taxons|filter(taxon => taxon.id is not null) %} + {% if taxon.children is not empty %} +
    • + {{ _self.tree_header(taxon) }} + {{ _self.render(taxon.children, true) }} +
    • + {% else %} +
    • + {{ _self.tree_link(taxon, path('sylius_admin_taxon_update', { id: taxon.id })) }} +
    • + {% endif %} + {% endfor %} +
    +{% endmacro %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections.html.twig new file mode 100644 index 0000000000..024b0d1e57 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections.html.twig @@ -0,0 +1,12 @@ +
    +
    +
    +
    + {% hook 'sections#left' %} +
    +
    + {% hook 'sections#right' %} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form.html.twig new file mode 100644 index 0000000000..43dd134ecd --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form.html.twig @@ -0,0 +1,16 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\Taxon\FormComponent #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
    + {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: hookable.configuration.render_rest|default(false)}) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details.html.twig new file mode 100644 index 0000000000..3fdd050726 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details.html.twig @@ -0,0 +1,5 @@ +
    +
    + {% hook 'details' %} +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/code.html.twig new file mode 100644 index 0000000000..fed599e8cf --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/code.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/enabled.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/enabled.html.twig new file mode 100644 index 0000000000..8edd587e78 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/enabled.html.twig @@ -0,0 +1 @@ +{{ form_row(hookable_metadata.context.form.enabled, { label_attr: { class: 'checkbox-switch' } }) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/parent.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/parent.html.twig new file mode 100644 index 0000000000..cf8a582113 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/details/parent.html.twig @@ -0,0 +1,5 @@ +{{ form_row(hookable_metadata.context.form.parent, { + parent_label_class: 'checkbox-switch', + search_url: path('sylius_admin_ajax_taxon_by_name_phrase'), + init_load_url: path('sylius_admin_ajax_taxon_by_code') +}) }} diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images.html.twig new file mode 100644 index 0000000000..03bc7415e1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images.html.twig @@ -0,0 +1,22 @@ +{% set form = hookable_metadata.context.form %} + +
    +
    +
    +

    + {{ 'sylius.ui.media'|trans }} +

    +
    +
    +
    + {% for image_form in form.images %} + {% hook 'images' with {form: image_form} %} + {% endfor %} +
    + +
    + {{ form_widget(form.images.vars.button_add, sylius_test_form_attribute('add-image')|sylius_merge_recursive({attr: {class: 'btn btn-outline-primary '}})) }} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image.html.twig new file mode 100644 index 0000000000..0141ee2333 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image.html.twig @@ -0,0 +1,14 @@ +{% set form = hookable_metadata.context.form %} + +
    +
    + {% hook "image#left" %} +
    +
    + {% hook "image#right" %} +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/button_delete.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/button_delete.html.twig new file mode 100644 index 0000000000..980c176229 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/button_delete.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_widget(hookable_metadata.context.form.vars.button_delete, sylius_test_form_attribute('delete-image')|sylius_merge_recursive({attr: { class: 'btn btn-outline-danger w-100'}})) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/file.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/file.html.twig new file mode 100644 index 0000000000..247a5c419a --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/file.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.file, sylius_test_form_attribute('file')) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/picture.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/picture.html.twig new file mode 100644 index 0000000000..da07d0ae1b --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/picture.html.twig @@ -0,0 +1,7 @@ +
    + {% if hookable_metadata.context.form.vars.value.path is not null %} + + {% else %} + + {% endif %} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/type.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/type.html.twig new file mode 100644 index 0000000000..a8942da99d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/images/image/type.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.type, sylius_test_form_attribute('type')) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/translations.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/translations.html.twig new file mode 100644 index 0000000000..15887f9d04 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/form/translations.html.twig @@ -0,0 +1,26 @@ +{% import '@SyliusAdmin/shared/helper/translations.html.twig' as _translations %} + +
    + {% set body %} + {% verbatim %} +
    + + + + + + +
    + {{ form_row(translationForm.name, { attr: { 'data-taxon-slug-target': 'sluggable', 'data-action': 'change->taxon-slug#generateSlug' } }) }} +
    +
    + {{ form_row(translationForm.slug, { attr: { 'data-taxon-slug-target': 'slug' } }) }} +
    +
    + {{ form_row(translationForm.description) }} +
    +
    + {% endverbatim %} + {% endset %} + {{ _translations.default(hookable_metadata.context.form.translations, body, {accordionId: 'taxon-translations'}) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/tree.html.twig b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/tree.html.twig new file mode 100644 index 0000000000..66b17ae21e --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/taxon/sections/tree.html.twig @@ -0,0 +1,16 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\Twig\Component\Taxon\TreeComponent #} + +{% import '@SyliusAdmin/taxon/helper/tree.html.twig' as taxonTree %} + +
    +
    +
    +
    + +
    +
    + {{ taxonTree.render(rootNodes) }} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form.html.twig new file mode 100644 index 0000000000..0b0f156073 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form.html.twig @@ -0,0 +1,16 @@ +{# Rendered with \Sylius\Bundle\AdminBundle\TwigComponent\Zone\FormComponent #} + +{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %} + +
    + {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {% if hookable_metadata.configuration.method is defined %} + + {% endif %} + {{ form_errors(form) }} + {{ form_widget(form._token) }} + + {% hook 'form' with { form } %} + + {{ form_end(form, {render_rest: false}) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections.html.twig new file mode 100644 index 0000000000..86a74da537 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections.html.twig @@ -0,0 +1 @@ +{% hook 'sections' %} diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details.html.twig new file mode 100644 index 0000000000..87b43e09be --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details.html.twig @@ -0,0 +1,7 @@ +
    +
    +
    + {% hook 'details' %} +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/code.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/code.html.twig new file mode 100644 index 0000000000..baf2a2f075 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/code.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.code, sylius_test_form_attribute('code')) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/name.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/name.html.twig new file mode 100644 index 0000000000..64f28fa1e2 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/name.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.name, sylius_test_form_attribute('name')) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/scope.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/scope.html.twig new file mode 100644 index 0000000000..3f44d671d1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/scope.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.scope, sylius_test_form_attribute('scope')) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/type.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/type.html.twig new file mode 100644 index 0000000000..5a0024b97d --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/details/type.html.twig @@ -0,0 +1,3 @@ +
    + {{ form_row(hookable_metadata.context.form.type, sylius_test_form_attribute('type')) }} +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/members.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/members.html.twig new file mode 100644 index 0000000000..9beabb68b1 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/members.html.twig @@ -0,0 +1,18 @@ +
    +
    +
    {{ form_label(hookable_metadata.context.form.members) }}
    +
    +
    +
    + {{ form_errors(hookable_metadata.context.form.members) }} + +
    + {% for member_form in hookable_metadata.context.form.members %} + {% hook 'members' with { member_form } %} + {% endfor %} + + {{ form_row(hookable_metadata.context.form.members.vars.button_add, sylius_test_form_attribute('add-member')) }} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/members/member.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/members/member.html.twig new file mode 100644 index 0000000000..14e7a8a0c5 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/form/sections/members/member.html.twig @@ -0,0 +1,12 @@ +
    +
    +
    +
    + {{ form_widget(hookable_metadata.context.member_form, sylius_test_form_attribute('member')) }} +
    +
    + {{ form_row(hookable_metadata.context.member_form.vars.button_delete, sylius_test_form_attribute('delete-zone-member')) }} +
    +
    +
    +
    diff --git a/src/Sylius/Bundle/AdminBundle/templates/zone/grid/field/type.html.twig b/src/Sylius/Bundle/AdminBundle/templates/zone/grid/field/type.html.twig new file mode 100644 index 0000000000..bd07f2c7f9 --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/templates/zone/grid/field/type.html.twig @@ -0,0 +1 @@ +{{ data }} diff --git a/src/Sylius/Bundle/AdminBundle/test/config/bundles.php b/src/Sylius/Bundle/AdminBundle/test/config/bundles.php index bb1e397266..b8180b5852 100644 --- a/src/Sylius/Bundle/AdminBundle/test/config/bundles.php +++ b/src/Sylius/Bundle/AdminBundle/test/config/bundles.php @@ -58,4 +58,8 @@ return [ SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], Sylius\Bundle\AdminBundle\SyliusAdminBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], + Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], + Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true], + Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true], ]; diff --git a/src/Sylius/Bundle/AdminBundle/test/config/routes/ux_live_component.yaml b/src/Sylius/Bundle/AdminBundle/test/config/routes/ux_live_component.yaml new file mode 100644 index 0000000000..e56523abfb --- /dev/null +++ b/src/Sylius/Bundle/AdminBundle/test/config/routes/ux_live_component.yaml @@ -0,0 +1,5 @@ +live_component: + resource: '@LiveComponentBundle/config/routes.php' + prefix: '/_components' + # adjust prefix to add localization to your components + #prefix: '/{_locale}/_components' diff --git a/src/Sylius/Bundle/ApiBundle/Exception/ProvinceCannotBeRemoved.php b/src/Sylius/Bundle/ApiBundle/Exception/ProvinceCannotBeRemoved.php index 1733eefe35..e165d72e25 100644 --- a/src/Sylius/Bundle/ApiBundle/Exception/ProvinceCannotBeRemoved.php +++ b/src/Sylius/Bundle/ApiBundle/Exception/ProvinceCannotBeRemoved.php @@ -16,7 +16,7 @@ namespace Sylius\Bundle\ApiBundle\Exception; final class ProvinceCannotBeRemoved extends \RuntimeException { public function __construct( - string $message = 'Cannot delete, the province is in use.', + string $message = 'Cannot delete, the Province is in use.', int $code = 0, ?\Throwable $previous = null, ) { diff --git a/src/Sylius/Bundle/ApiBundle/Exception/ZoneCannotBeRemoved.php b/src/Sylius/Bundle/ApiBundle/Exception/ZoneCannotBeRemoved.php index 19ddbc94cc..b0703d629a 100644 --- a/src/Sylius/Bundle/ApiBundle/Exception/ZoneCannotBeRemoved.php +++ b/src/Sylius/Bundle/ApiBundle/Exception/ZoneCannotBeRemoved.php @@ -16,7 +16,7 @@ namespace Sylius\Bundle\ApiBundle\Exception; final class ZoneCannotBeRemoved extends \RuntimeException { public function __construct( - string $message = 'Cannot delete, the zone is in use.', + string $message = 'Cannot delete, the Zone is in use.', int $code = 0, ?\Throwable $previous = null, ) { diff --git a/src/Sylius/Bundle/ApiBundle/Tests/Application/config/bundles.php b/src/Sylius/Bundle/ApiBundle/Tests/Application/config/bundles.php index eab508bff6..d4b15310c7 100644 --- a/src/Sylius/Bundle/ApiBundle/Tests/Application/config/bundles.php +++ b/src/Sylius/Bundle/ApiBundle/Tests/Application/config/bundles.php @@ -61,4 +61,5 @@ return [ SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], ]; diff --git a/src/Sylius/Bundle/ChannelBundle/composer.json b/src/Sylius/Bundle/ChannelBundle/composer.json index ff2a096417..721f5b6fa7 100644 --- a/src/Sylius/Bundle/ChannelBundle/composer.json +++ b/src/Sylius/Bundle/ChannelBundle/composer.json @@ -39,11 +39,10 @@ "symfony/browser-kit": "^6.4.0", "symfony/dependency-injection": "^6.4.1", "symfony/form": "^6.4.1", - "twig/twig": "^2.12 || ^3.3" + "twig/twig": "~3.8.0" }, "conflict": { - "doctrine/orm": ">= 2.16.0", - "twig/twig": "3.9.0" + "doctrine/orm": ">= 2.16.0" }, "config": { "allow-plugins": { diff --git a/src/Sylius/Bundle/CoreBundle/Controller/PaymentMethodController.php b/src/Sylius/Bundle/CoreBundle/Controller/PaymentMethodController.php index fdb94c3f1c..ea084801f5 100644 --- a/src/Sylius/Bundle/CoreBundle/Controller/PaymentMethodController.php +++ b/src/Sylius/Bundle/CoreBundle/Controller/PaymentMethodController.php @@ -17,6 +17,9 @@ use Sylius\Bundle\ResourceBundle\Controller\ResourceController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +/** + * TODO: Remove this controller + */ class PaymentMethodController extends ResourceController { public function getPaymentGatewaysAction(Request $request, string $template): Response diff --git a/src/Sylius/Bundle/CoreBundle/Form/Extension/ChannelTypeExtension.php b/src/Sylius/Bundle/CoreBundle/Form/Extension/ChannelTypeExtension.php index 5ea7e076e5..3380a48463 100644 --- a/src/Sylius/Bundle/CoreBundle/Form/Extension/ChannelTypeExtension.php +++ b/src/Sylius/Bundle/CoreBundle/Form/Extension/ChannelTypeExtension.php @@ -28,6 +28,7 @@ use Sylius\Bundle\ThemeBundle\Form\Type\ThemeNameChoiceType; use Sylius\Component\Core\Model\Scope; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; @@ -58,6 +59,7 @@ final class ChannelTypeExtension extends AbstractTypeExtension 'label' => 'sylius.form.channel.countries', 'required' => false, 'multiple' => true, + 'expanded' => false, ]) ->add('defaultTaxZone', ZoneChoiceType::class, [ 'required' => false, @@ -93,8 +95,15 @@ final class ChannelTypeExtension extends AbstractTypeExtension 'label' => 'sylius.form.channel.account_verification_required', 'required' => false, ]) - ->add('shippingAddressInCheckoutRequired', CheckboxType::class, [ + ->add('shippingAddressInCheckoutRequired', ChoiceType::class, [ 'label' => 'sylius.form.channel.shipping_address_in_checkout_required', + 'choices' => [ + 'sylius.ui.billing_address' => false, + 'sylius.ui.shipping_address' => true, + ], + 'placeholder' => false, + 'multiple' => false, + 'expanded' => true, 'required' => false, ]) ->add('shopBillingData', ShopBillingDataType::class, [ diff --git a/src/Sylius/Bundle/CoreBundle/Form/Extension/OrderTypeExtension.php b/src/Sylius/Bundle/CoreBundle/Form/Extension/OrderTypeExtension.php index acb7f5777b..daac6a4c28 100644 --- a/src/Sylius/Bundle/CoreBundle/Form/Extension/OrderTypeExtension.php +++ b/src/Sylius/Bundle/CoreBundle/Form/Extension/OrderTypeExtension.php @@ -17,17 +17,29 @@ use Sylius\Bundle\AddressingBundle\Form\Type\AddressType; use Sylius\Bundle\OrderBundle\Form\Type\OrderType; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; final class OrderTypeExtension extends AbstractTypeExtension { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('shippingAddress', AddressType::class) - ->add('billingAddress', AddressType::class) + ->add('shippingAddress', AddressType::class, [ + 'add_build_address_form_subscriber' => $options['add_build_address_form_subscriber'], + ]) + ->add('billingAddress', AddressType::class, [ + 'add_build_address_form_subscriber' => $options['add_build_address_form_subscriber'], + ]) ; } + public function configureOptions(OptionsResolver $resolver): void + { + parent::configureOptions($resolver); + + $resolver->setDefaults(['add_build_address_form_subscriber' => true]); + } + public static function getExtendedTypes(): iterable { return [OrderType::class]; diff --git a/src/Sylius/Bundle/CoreBundle/Form/Extension/PaymentMethodTypeExtension.php b/src/Sylius/Bundle/CoreBundle/Form/Extension/PaymentMethodTypeExtension.php index 021552da59..296d598777 100644 --- a/src/Sylius/Bundle/CoreBundle/Form/Extension/PaymentMethodTypeExtension.php +++ b/src/Sylius/Bundle/CoreBundle/Form/Extension/PaymentMethodTypeExtension.php @@ -27,7 +27,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; final class PaymentMethodTypeExtension extends AbstractTypeExtension { - public function __construct(private GatewayConfigGroupsGenerator $gatewayConfigGroupsGenerator) + public function __construct(private readonly GatewayConfigGroupsGenerator $gatewayConfigGroupsGenerator) { } diff --git a/src/Sylius/Bundle/CoreBundle/Form/Type/Product/ProductImageType.php b/src/Sylius/Bundle/CoreBundle/Form/Type/Product/ProductImageType.php index 3486d0144e..22256e0e1a 100644 --- a/src/Sylius/Bundle/CoreBundle/Form/Type/Product/ProductImageType.php +++ b/src/Sylius/Bundle/CoreBundle/Form/Type/Product/ProductImageType.php @@ -13,9 +13,11 @@ declare(strict_types=1); namespace Sylius\Bundle\CoreBundle\Form\Type\Product; +use Doctrine\ORM\QueryBuilder; use Sylius\Bundle\CoreBundle\Form\Type\ImageType; -use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType; +use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository; use Sylius\Component\Core\Model\ProductInterface; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; @@ -23,19 +25,30 @@ use Symfony\Component\OptionsResolver\OptionsResolver; final class ProductImageType extends ImageType { + public function __construct(string $dataClass, private string $productVariantClass, array $validationGroups = []) + { + parent::__construct($dataClass, $validationGroups); + } + public function buildForm(FormBuilderInterface $builder, array $options): void { parent::buildForm($builder, $options); - if (isset($options['product']) && $options['product'] instanceof ProductInterface) { + if (isset($options['product']) && $options['product'] instanceof ProductInterface && $options['product']->getId() !== null) { $builder - ->add('productVariants', ResourceAutocompleteChoiceType::class, [ + ->add('productVariants', EntityType::class, [ + 'class' => $this->productVariantClass, 'label' => 'sylius.ui.product_variants', 'multiple' => true, 'required' => false, - 'choice_name' => 'descriptor', + 'choice_label' => 'descriptor', 'choice_value' => 'code', - 'resource' => 'sylius.product_variant', + 'query_builder' => function (EntityRepository $er) use ($options): QueryBuilder { + return $er->createQueryBuilder('o') + ->where('o.product = :product') + ->setParameter('product', $options['product']) + ; + }, ]) ; } diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/services/form.xml b/src/Sylius/Bundle/CoreBundle/Resources/config/services/form.xml index 6d30383539..0bf63bf0f9 100644 --- a/src/Sylius/Bundle/CoreBundle/Resources/config/services/form.xml +++ b/src/Sylius/Bundle/CoreBundle/Resources/config/services/form.xml @@ -67,10 +67,6 @@ - - - - @@ -153,6 +149,7 @@ %sylius.model.product_image.class% + %sylius.model.product_variant.class% %sylius.form.type.product_image.validation_groups% diff --git a/src/Sylius/Bundle/CoreBundle/test/config/bundles.php b/src/Sylius/Bundle/CoreBundle/test/config/bundles.php index 20e140f2bc..991e80816c 100644 --- a/src/Sylius/Bundle/CoreBundle/test/config/bundles.php +++ b/src/Sylius/Bundle/CoreBundle/test/config/bundles.php @@ -55,4 +55,5 @@ return [ Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true], Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], ]; diff --git a/src/Sylius/Bundle/CurrencyBundle/composer.json b/src/Sylius/Bundle/CurrencyBundle/composer.json index 7fe410e570..c1c9de5549 100644 --- a/src/Sylius/Bundle/CurrencyBundle/composer.json +++ b/src/Sylius/Bundle/CurrencyBundle/composer.json @@ -34,7 +34,7 @@ }, "conflict": { "doctrine/orm": ">= 2.16.0", - "twig/twig": "^1.0 || 3.9.0" + "twig/twig": "3.9.0" }, "require-dev": { "doctrine/orm": "^2.13", @@ -45,7 +45,7 @@ "symfony/browser-kit": "^6.4.0", "symfony/dependency-injection": "^6.4.1", "symfony/form": "^6.4.1", - "twig/twig": "^2.12 || ^3.3" + "twig/twig": "~3.8.0" }, "config": { "allow-plugins": { diff --git a/src/Sylius/Bundle/CustomerBundle/composer.json b/src/Sylius/Bundle/CustomerBundle/composer.json index 12cb0f1c7f..e29b10cb84 100644 --- a/src/Sylius/Bundle/CustomerBundle/composer.json +++ b/src/Sylius/Bundle/CustomerBundle/composer.json @@ -44,8 +44,7 @@ "webmozart/assert": "^1.9" }, "conflict": { - "doctrine/orm": ">= 2.16.0", - "twig/twig": "^3.0" + "doctrine/orm": ">= 2.16.0" }, "require-dev": { "phpspec/phpspec": "^7.2", diff --git a/src/Sylius/Bundle/InventoryBundle/composer.json b/src/Sylius/Bundle/InventoryBundle/composer.json index e5d4e90d8e..cd79b9f094 100644 --- a/src/Sylius/Bundle/InventoryBundle/composer.json +++ b/src/Sylius/Bundle/InventoryBundle/composer.json @@ -35,7 +35,7 @@ }, "conflict": { "doctrine/orm": ">= 2.16.0", - "twig/twig": "^1.0 || 3.9.0" + "twig/twig": "3.9.0" }, "require-dev": { "doctrine/orm": "^2.13", @@ -44,7 +44,7 @@ "polishsymfonycommunity/symfony-mocker-container": "^1.0", "symfony/browser-kit": "^6.4.0", "symfony/dependency-injection": "^6.4.1", - "twig/twig": "^2.12 || ^3.3" + "twig/twig": "~3.8.0" }, "config": { "allow-plugins": { diff --git a/src/Sylius/Bundle/LocaleBundle/composer.json b/src/Sylius/Bundle/LocaleBundle/composer.json index f943f7f8b8..f796c6368f 100644 --- a/src/Sylius/Bundle/LocaleBundle/composer.json +++ b/src/Sylius/Bundle/LocaleBundle/composer.json @@ -35,7 +35,7 @@ }, "conflict": { "doctrine/orm": ">= 2.16.0", - "twig/twig": "^1.0 || 3.9.0" + "twig/twig": "3.9.0" }, "require-dev": { "doctrine/orm": "^2.13", @@ -46,7 +46,7 @@ "polishsymfonycommunity/symfony-mocker-container": "^1.0", "symfony/browser-kit": "^6.4.0", "symfony/dependency-injection": "^6.4.1", - "twig/twig": "^2.12 || ^3.3" + "twig/twig": "~3.8.0" }, "config": { "allow-plugins": { diff --git a/src/Sylius/Bundle/MoneyBundle/composer.json b/src/Sylius/Bundle/MoneyBundle/composer.json index d7ec35d296..f60b355f28 100644 --- a/src/Sylius/Bundle/MoneyBundle/composer.json +++ b/src/Sylius/Bundle/MoneyBundle/composer.json @@ -34,7 +34,7 @@ }, "conflict": { "doctrine/orm": ">= 2.16.0", - "twig/twig": "^1.0 || 3.9.0" + "twig/twig": "3.9.0" }, "require-dev": { "doctrine/orm": "^2.13", @@ -45,7 +45,7 @@ "symfony/browser-kit": "^6.4.0", "symfony/dependency-injection": "^6.4.1", "symfony/form": "^6.4.1", - "twig/twig": "^2.12 || ^3.3" + "twig/twig": "~3.8.0" }, "config": { "allow-plugins": { diff --git a/src/Sylius/Bundle/OrderBundle/composer.json b/src/Sylius/Bundle/OrderBundle/composer.json index 96c19841c4..11793a4677 100644 --- a/src/Sylius/Bundle/OrderBundle/composer.json +++ b/src/Sylius/Bundle/OrderBundle/composer.json @@ -39,8 +39,7 @@ }, "conflict": { "doctrine/orm": ">= 2.16.0", - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "^1.0 || ^3.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "doctrine/orm": "^2.13", diff --git a/src/Sylius/Bundle/PaymentBundle/Resources/translations/messages.en.yml b/src/Sylius/Bundle/PaymentBundle/Resources/translations/messages.en.yml index ad01ffece1..f7a10edfbe 100644 --- a/src/Sylius/Bundle/PaymentBundle/Resources/translations/messages.en.yml +++ b/src/Sylius/Bundle/PaymentBundle/Resources/translations/messages.en.yml @@ -28,7 +28,7 @@ sylius: refunded: Refunded payment_method: description: Description - enabled: Enabled? + enabled: Enabled instructions: Instructions name: Name position: Position diff --git a/src/Sylius/Bundle/PaymentBundle/composer.json b/src/Sylius/Bundle/PaymentBundle/composer.json index 6f3a7aeaed..dce6337dad 100644 --- a/src/Sylius/Bundle/PaymentBundle/composer.json +++ b/src/Sylius/Bundle/PaymentBundle/composer.json @@ -32,8 +32,7 @@ "symfony/framework-bundle": "^6.4.1" }, "conflict": { - "doctrine/orm": "2.15.2", - "twig/twig": "^3.0" + "doctrine/orm": "2.15.2" }, "require-dev": { "doctrine/orm": "^2.13", diff --git a/src/Sylius/Bundle/PayumBundle/Resources/config/validation/GatewayConfig.xml b/src/Sylius/Bundle/PayumBundle/Resources/config/validation/GatewayConfig.xml index a5cc19b7a4..108719f779 100644 --- a/src/Sylius/Bundle/PayumBundle/Resources/config/validation/GatewayConfig.xml +++ b/src/Sylius/Bundle/PayumBundle/Resources/config/validation/GatewayConfig.xml @@ -81,6 +81,9 @@ + diff --git a/src/Sylius/Bundle/ProductBundle/Doctrine/ORM/ProductOptionRepository.php b/src/Sylius/Bundle/ProductBundle/Doctrine/ORM/ProductOptionRepository.php index cbb6707c54..52e519cdf0 100644 --- a/src/Sylius/Bundle/ProductBundle/Doctrine/ORM/ProductOptionRepository.php +++ b/src/Sylius/Bundle/ProductBundle/Doctrine/ORM/ProductOptionRepository.php @@ -47,7 +47,7 @@ class ProductOptionRepository extends EntityRepository implements ProductOptionR ; } - public function findByPhrase(string $phrase, string $locale, int $limit = 10): array + public function findByPhrase(string $phrase, string $locale, int $limit = 10, ?array $excludes = null): array { $subqueryBuilder = $this->createQueryBuilder('sq') ->innerJoin('sq.translations', 'translation', 'WITH', 'translation.name LIKE :name') @@ -58,6 +58,12 @@ class ProductOptionRepository extends EntityRepository implements ProductOptionR $queryBuilder = $this->createQueryBuilder('o'); + if (null !== $excludes) { + $queryBuilder + ->andWhere($queryBuilder->expr()->notIn('o.code', $excludes)) + ; + } + /** @var ProductOptionInterface[] $results */ $results = $queryBuilder ->andWhere($queryBuilder->expr()->in('o', $subqueryBuilder->getDQL())) diff --git a/src/Sylius/Bundle/ProductBundle/Form/DataTransformer/ProductsToProductAssociationsTransformer.php b/src/Sylius/Bundle/ProductBundle/Form/DataTransformer/ProductsToProductAssociationsTransformer.php index 6ee25e2bc7..58a7ebcbf5 100644 --- a/src/Sylius/Bundle/ProductBundle/Form/DataTransformer/ProductsToProductAssociationsTransformer.php +++ b/src/Sylius/Bundle/ProductBundle/Form/DataTransformer/ProductsToProductAssociationsTransformer.php @@ -29,10 +29,15 @@ final class ProductsToProductAssociationsTransformer implements DataTransformerI /** @var Collection */ private ?Collection $productAssociations = null; + /** + * @param FactoryInterface $productAssociationFactory + * @param ProductRepositoryInterface $productRepository + * @param RepositoryInterface $productAssociationTypeRepository + */ public function __construct( - private FactoryInterface $productAssociationFactory, - private ProductRepositoryInterface $productRepository, - private RepositoryInterface $productAssociationTypeRepository, + private readonly FactoryInterface $productAssociationFactory, + private readonly ProductRepositoryInterface $productRepository, + private readonly RepositoryInterface $productAssociationTypeRepository, ) { } diff --git a/src/Sylius/Bundle/ProductBundle/Form/EventSubscriber/ProductOptionFieldSubscriber.php b/src/Sylius/Bundle/ProductBundle/Form/EventSubscriber/ProductOptionFieldSubscriber.php index 298b667dca..14db059ea6 100644 --- a/src/Sylius/Bundle/ProductBundle/Form/EventSubscriber/ProductOptionFieldSubscriber.php +++ b/src/Sylius/Bundle/ProductBundle/Form/EventSubscriber/ProductOptionFieldSubscriber.php @@ -13,18 +13,20 @@ declare(strict_types=1); namespace Sylius\Bundle\ProductBundle\Form\EventSubscriber; -use Sylius\Bundle\ProductBundle\Form\Type\ProductOptionAutocompleteType; use Sylius\Component\Product\Model\ProductInterface; use Sylius\Component\Product\Resolver\ProductVariantResolverInterface; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Webmozart\Assert\Assert; -final class ProductOptionFieldSubscriber implements EventSubscriberInterface +final readonly class ProductOptionFieldSubscriber implements EventSubscriberInterface { - public function __construct(private ProductVariantResolverInterface $variantResolver) - { + public function __construct( + private ProductVariantResolverInterface $variantResolver, + private string $productOptionClass, + ) { } public static function getSubscribedEvents(): array @@ -46,11 +48,18 @@ final class ProductOptionFieldSubscriber implements EventSubscriberInterface /** Options should be disabled for configurable product if it has at least one defined variant */ $disableOptions = null !== $this->variantResolver->getVariant($product); - $form->add('options', ProductOptionAutocompleteType::class, [ + $form->add('options', EntityType::class, [ 'required' => false, 'disabled' => $disableOptions, 'multiple' => true, 'label' => 'sylius.form.product.options', + 'class' => $this->productOptionClass, + 'choice_name' => 'code', + 'choice_label' => 'name', + 'autocomplete' => true, + 'attr' => [ + 'data-test-product-options-autocomplete' => '', + ], ]); } } diff --git a/src/Sylius/Bundle/ProductBundle/Form/Type/ProductAssociationsType.php b/src/Sylius/Bundle/ProductBundle/Form/Type/ProductAssociationsType.php index 092020d39f..fa2e6cd459 100644 --- a/src/Sylius/Bundle/ProductBundle/Form/Type/ProductAssociationsType.php +++ b/src/Sylius/Bundle/ProductBundle/Form/Type/ProductAssociationsType.php @@ -13,8 +13,11 @@ declare(strict_types=1); namespace Sylius\Bundle\ProductBundle\Form\Type; +use Doctrine\Common\Collections\Collection; use Sylius\Bundle\ResourceBundle\Form\Type\FixedCollectionType; +use Sylius\Component\Product\Model\ProductAssociationInterface; use Sylius\Component\Product\Model\ProductAssociationTypeInterface; +use Sylius\Component\Product\Model\ProductInterface; use Sylius\Component\Resource\Repository\RepositoryInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\DataTransformerInterface; @@ -24,9 +27,13 @@ use Symfony\Component\OptionsResolver\OptionsResolver; final class ProductAssociationsType extends AbstractType { + /** + * @param RepositoryInterface $productAssociationTypeRepository + * @param DataTransformerInterface, Collection> $productsToProductAssociationsTransformer + */ public function __construct( - private RepositoryInterface $productAssociationTypeRepository, - private DataTransformerInterface $productsToProductAssociationsTransformer, + private readonly RepositoryInterface $productAssociationTypeRepository, + private readonly DataTransformerInterface $productsToProductAssociationsTransformer, ) { } diff --git a/src/Sylius/Bundle/ProductBundle/Form/Type/ProductType.php b/src/Sylius/Bundle/ProductBundle/Form/Type/ProductType.php index 9287883c9e..34f95a0281 100644 --- a/src/Sylius/Bundle/ProductBundle/Form/Type/ProductType.php +++ b/src/Sylius/Bundle/ProductBundle/Form/Type/ProductType.php @@ -16,7 +16,6 @@ namespace Sylius\Bundle\ProductBundle\Form\Type; use Sylius\Bundle\ProductBundle\Form\EventSubscriber\BuildAttributesFormSubscriber; use Sylius\Bundle\ProductBundle\Form\EventSubscriber\ProductOptionFieldSubscriber; use Sylius\Bundle\ProductBundle\Form\EventSubscriber\SimpleProductSubscriber; -use Sylius\Bundle\ResourceBundle\Form\EventSubscriber\AddCodeFormSubscriber; use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType; use Sylius\Bundle\ResourceBundle\Form\Type\ResourceTranslationsType; use Sylius\Component\Product\Resolver\ProductVariantResolverInterface; @@ -24,7 +23,10 @@ use Sylius\Component\Resource\Factory\FactoryInterface; use Sylius\Component\Resource\Translation\Provider\TranslationLocaleProviderInterface; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; final class ProductType extends AbstractResourceType { @@ -33,6 +35,7 @@ final class ProductType extends AbstractResourceType */ public function __construct( string $dataClass, + private string $productOptionClass, array $validationGroups, private ProductVariantResolverInterface $variantResolver, private FactoryInterface $attributeValueFactory, @@ -44,10 +47,10 @@ final class ProductType extends AbstractResourceType public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->addEventSubscriber(new AddCodeFormSubscriber()) - ->addEventSubscriber(new ProductOptionFieldSubscriber($this->variantResolver)) + ->addEventSubscriber(new ProductOptionFieldSubscriber($this->variantResolver, $this->productOptionClass)) ->addEventSubscriber(new SimpleProductSubscriber()) ->addEventSubscriber(new BuildAttributesFormSubscriber($this->attributeValueFactory, $this->localeProvider)) + ->addEventListener(FormEvents::PRE_SET_DATA, $this->addCodeField(...)) ->add('enabled', CheckboxType::class, [ 'required' => false, 'label' => 'sylius.form.product.enabled', @@ -71,6 +74,20 @@ final class ProductType extends AbstractResourceType ; } + private function addCodeField(FormEvent $event): void + { + $product = $event->getData(); + + if (null === $product) { + return; + } + + $event->getForm()->add('code', TextType::class, [ + 'label' => 'sylius.ui.code', + 'disabled' => null !== $product->getId(), + ]); + } + public function getBlockPrefix(): string { return 'sylius_product'; diff --git a/src/Sylius/Bundle/ProductBundle/Resources/config/services/form.xml b/src/Sylius/Bundle/ProductBundle/Resources/config/services/form.xml index 45079c06a2..9bc70a1ef2 100644 --- a/src/Sylius/Bundle/ProductBundle/Resources/config/services/form.xml +++ b/src/Sylius/Bundle/ProductBundle/Resources/config/services/form.xml @@ -127,6 +127,7 @@ %sylius.model.product.class% + %sylius.model.product_option.class% %sylius.form.type.product.validation_groups% diff --git a/src/Sylius/Bundle/PromotionBundle/Form/Type/AbstractConfigurablePromotionElementType.php b/src/Sylius/Bundle/PromotionBundle/Form/Type/AbstractConfigurablePromotionElementType.php index 61edeb4dd5..06897df7f7 100644 --- a/src/Sylius/Bundle/PromotionBundle/Form/Type/AbstractConfigurablePromotionElementType.php +++ b/src/Sylius/Bundle/PromotionBundle/Form/Type/AbstractConfigurablePromotionElementType.php @@ -53,7 +53,7 @@ abstract class AbstractConfigurablePromotionElementType extends AbstractResource ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event): void { $data = $event->getData(); - if (!isset($data['type'])) { + if (!isset($data['type']) || $data['type'] === '') { return; } diff --git a/src/Sylius/Bundle/PromotionBundle/Form/Type/PromotionType.php b/src/Sylius/Bundle/PromotionBundle/Form/Type/PromotionType.php index 931976bba2..d584f0c40c 100644 --- a/src/Sylius/Bundle/PromotionBundle/Form/Type/PromotionType.php +++ b/src/Sylius/Bundle/PromotionBundle/Form/Type/PromotionType.php @@ -52,6 +52,7 @@ final class PromotionType extends AbstractResourceType ]) ->add('appliesToDiscounted', CheckboxType::class, [ 'label' => 'sylius.form.promotion.applies_to_discounted', + 'help' => 'sylius.form.promotion.applies_to_discounted_details', ]) ->add('usageLimit', IntegerType::class, [ 'label' => 'sylius.form.promotion.usage_limit', diff --git a/src/Sylius/Bundle/PromotionBundle/composer.json b/src/Sylius/Bundle/PromotionBundle/composer.json index f3aecf9d21..4f6f5a8ce1 100644 --- a/src/Sylius/Bundle/PromotionBundle/composer.json +++ b/src/Sylius/Bundle/PromotionBundle/composer.json @@ -39,8 +39,7 @@ }, "conflict": { "doctrine/orm": "2.15.2", - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "^3.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "doctrine/orm": "^2.13", diff --git a/src/Sylius/Bundle/ReviewBundle/composer.json b/src/Sylius/Bundle/ReviewBundle/composer.json index 06f53b14ed..27299dff6d 100644 --- a/src/Sylius/Bundle/ReviewBundle/composer.json +++ b/src/Sylius/Bundle/ReviewBundle/composer.json @@ -47,8 +47,7 @@ "symfony/framework-bundle": "^6.4.1" }, "conflict": { - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "^3.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "phpspec/phpspec": "^7.2", diff --git a/src/Sylius/Bundle/ShippingBundle/Form/Type/AbstractConfigurableShippingMethodElementType.php b/src/Sylius/Bundle/ShippingBundle/Form/Type/AbstractConfigurableShippingMethodElementType.php index 288554df00..745803f873 100644 --- a/src/Sylius/Bundle/ShippingBundle/Form/Type/AbstractConfigurableShippingMethodElementType.php +++ b/src/Sylius/Bundle/ShippingBundle/Form/Type/AbstractConfigurableShippingMethodElementType.php @@ -53,7 +53,7 @@ abstract class AbstractConfigurableShippingMethodElementType extends AbstractRes ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event): void { $data = $event->getData(); - if (!isset($data['type'])) { + if (!isset($data['type']) || $data['type'] === '') { return; } diff --git a/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleChoiceType.php b/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleChoiceType.php index 46e08a77d0..43d5f3d45e 100644 --- a/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleChoiceType.php +++ b/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleChoiceType.php @@ -27,6 +27,7 @@ final class ShippingMethodRuleChoiceType extends AbstractType { $resolver->setDefaults([ 'choices' => array_flip($this->rules), + 'placeholder' => 'sylius.form.shipping_method_rule.select', ]); } diff --git a/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleType.php b/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleType.php index 7264ca4292..bb90dd023d 100644 --- a/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleType.php +++ b/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodRuleType.php @@ -24,9 +24,6 @@ final class ShippingMethodRuleType extends AbstractConfigurableShippingMethodEle $builder ->add('type', ShippingMethodRuleChoiceType::class, [ 'label' => 'sylius.form.shipping_method_rule.type', - 'attr' => [ - 'data-form-collection' => 'update', - ], ]) ; } diff --git a/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodType.php b/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodType.php index d6b7660005..20452497f9 100644 --- a/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodType.php +++ b/src/Sylius/Bundle/ShippingBundle/Form/Type/ShippingMethodType.php @@ -70,6 +70,7 @@ final class ShippingMethodType extends AbstractResourceType ]) ->add('calculator', CalculatorChoiceType::class, [ 'label' => 'sylius.form.shipping_method.calculator', + 'placeholder' => 'sylius.form.shipping_method.select_calculator', ]) ->add('enabled', CheckboxType::class, [ 'label' => 'sylius.form.locale.enabled', @@ -135,6 +136,10 @@ final class ShippingMethodType extends AbstractResourceType private function addConfigurationField(FormInterface $form, string $calculatorName): void { + if ($calculatorName === '') { + return; + } + /** @var CalculatorInterface $calculator */ $calculator = $this->calculatorRegistry->get($calculatorName); diff --git a/src/Sylius/Bundle/ShippingBundle/Resources/translations/messages.en.yml b/src/Sylius/Bundle/ShippingBundle/Resources/translations/messages.en.yml index c1ce734af2..02a5b5ffa8 100644 --- a/src/Sylius/Bundle/ShippingBundle/Resources/translations/messages.en.yml +++ b/src/Sylius/Bundle/ShippingBundle/Resources/translations/messages.en.yml @@ -46,6 +46,7 @@ sylius: rules_help: Use rules to decide whether this shipping method can be applied to a given order. If a rule is true this shipping method can be applied. Notice that if you add multiple rules, all rules has to be true. + select_calculator: Select a calculator tax_category: Tax category translations: Translations shipping_method_rule: @@ -57,3 +58,4 @@ sylius: total_weight_less_than_or_equal: Total weight less than or equal weight: Weight amount: Amount + select: Select a rule type diff --git a/src/Sylius/Bundle/ShippingBundle/composer.json b/src/Sylius/Bundle/ShippingBundle/composer.json index 678a8a88eb..fe9433b7bf 100644 --- a/src/Sylius/Bundle/ShippingBundle/composer.json +++ b/src/Sylius/Bundle/ShippingBundle/composer.json @@ -38,8 +38,7 @@ }, "conflict": { "doctrine/orm": "2.15.2", - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "^3.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "doctrine/orm": "^2.13", diff --git a/src/Sylius/Bundle/ShopBundle/composer.json b/src/Sylius/Bundle/ShopBundle/composer.json index 4ee6c4a5ee..55245bbf4d 100644 --- a/src/Sylius/Bundle/ShopBundle/composer.json +++ b/src/Sylius/Bundle/ShopBundle/composer.json @@ -32,8 +32,8 @@ "symfony/framework-bundle": "^6.4.1", "symfony/security-bundle": "^6.4.0", "symfony/webpack-encore-bundle": "^1.17.1", - "twig/intl-extra": "^2.12 || ^3.4", - "twig/twig": "^2.12 || ^3.3" + "twig/intl-extra": "~3.8.0", + "twig/twig": "~3.8.0" }, "require-dev": { "matthiasnoback/symfony-config-test": "^4.2", @@ -43,9 +43,6 @@ "phpunit/phpunit": "^9.5", "symfony/dependency-injection": "^6.4.1" }, - "conflict": { - "twig/twig": "3.9.0" - }, "config": { "allow-plugins": { "symfony/flex": true diff --git a/src/Sylius/Bundle/TaxationBundle/composer.json b/src/Sylius/Bundle/TaxationBundle/composer.json index 6880d4a745..5e5c4ebde8 100644 --- a/src/Sylius/Bundle/TaxationBundle/composer.json +++ b/src/Sylius/Bundle/TaxationBundle/composer.json @@ -37,8 +37,7 @@ }, "conflict": { "doctrine/orm": ">= 2.16.0", - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "^3.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "doctrine/orm": "^2.13", diff --git a/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonPositionController.php b/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonPositionController.php deleted file mode 100644 index 61255cf700..0000000000 --- a/src/Sylius/Bundle/TaxonomyBundle/Controller/TaxonPositionController.php +++ /dev/null @@ -1,70 +0,0 @@ - $taxonRepository - */ - public function __construct( - private TaxonRepositoryInterface $taxonRepository, - private ObjectManager $taxonManager, - ) { - } - - public function moveUpAction(int $id): Response - { - $taxonToBeMoved = $this->findTaxonOr404($id); - - if ($taxonToBeMoved->getPosition() > 0) { - $taxonToBeMoved->setPosition($taxonToBeMoved->getPosition() - 1); - $this->taxonManager->flush(); - } - - return new JsonResponse('', Response::HTTP_NO_CONTENT); - } - - public function moveDownAction(int $id): Response - { - $taxonToBeMoved = $this->findTaxonOr404($id); - - $taxonToBeMoved->setPosition($taxonToBeMoved->getPosition() + 1); - $this->taxonManager->flush(); - - return new JsonResponse('', Response::HTTP_NO_CONTENT); - } - - private function findTaxonOr404(int $id): TaxonInterface - { - /** @var TaxonInterface|null $taxon */ - $taxon = $this->taxonRepository->find($id); - - if (null === $taxon) { - throw new NotFoundHttpException(sprintf('Taxon with id %d does not exist.', $id)); - } - - Assert::isInstanceOf($taxon, TaxonInterface::class); - - return $taxon; - } -} diff --git a/src/Sylius/Bundle/TaxonomyBundle/Doctrine/ORM/TaxonRepository.php b/src/Sylius/Bundle/TaxonomyBundle/Doctrine/ORM/TaxonRepository.php index da6df11cdb..8f232ce4a3 100644 --- a/src/Sylius/Bundle/TaxonomyBundle/Doctrine/ORM/TaxonRepository.php +++ b/src/Sylius/Bundle/TaxonomyBundle/Doctrine/ORM/TaxonRepository.php @@ -123,7 +123,7 @@ class TaxonRepository extends EntityRepository implements TaxonRepositoryInterfa return $this->findRootNodes(); } - public function findByNamePart(string $phrase, ?string $locale = null, ?int $limit = null): array + public function findByNamePart(string $phrase, ?string $locale = null, ?int $limit = null, ?array $excludes = null): array { $subqueryBuilder = $this->createQueryBuilder('sq') ->innerJoin('sq.translations', 'translation', 'WITH', 'translation.name LIKE :name') @@ -134,6 +134,13 @@ class TaxonRepository extends EntityRepository implements TaxonRepositoryInterfa $queryBuilder = $this->createQueryBuilder('o'); + if (null !== $excludes) { + $queryBuilder + ->andWhere($queryBuilder->expr()->notIn('o.code', ':excludes')) + ->setParameter('excludes', $excludes) + ; + } + /** @var TaxonInterface[] $results */ $results = $queryBuilder ->andWhere($queryBuilder->expr()->in('o', $subqueryBuilder->getDQL())) diff --git a/src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.xml b/src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.xml index 505e391180..f27c592d3f 100644 --- a/src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.xml +++ b/src/Sylius/Bundle/TaxonomyBundle/Resources/config/services.xml @@ -26,11 +26,6 @@ - - - - - diff --git a/src/Sylius/Bundle/TaxonomyBundle/composer.json b/src/Sylius/Bundle/TaxonomyBundle/composer.json index e31ce2cd93..04faf5d616 100644 --- a/src/Sylius/Bundle/TaxonomyBundle/composer.json +++ b/src/Sylius/Bundle/TaxonomyBundle/composer.json @@ -36,8 +36,7 @@ }, "conflict": { "doctrine/orm": "2.15.2", - "stof/doctrine-extensions-bundle": "1.8.0", - "twig/twig": "^3.0" + "stof/doctrine-extensions-bundle": "1.8.0" }, "require-dev": { "doctrine/orm": "^2.13", diff --git a/src/Sylius/Bundle/UiBundle/ContextProvider/CompositeContextProvider.php b/src/Sylius/Bundle/UiBundle/ContextProvider/CompositeContextProvider.php new file mode 100644 index 0000000000..559d28f493 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/ContextProvider/CompositeContextProvider.php @@ -0,0 +1,56 @@ + */ + private array $contextProviders; + + /** + * @param iterable $contextProviders + */ + public function __construct(iterable $contextProviders) + { + Assert::allIsInstanceOf($contextProviders, ContextProviderInterface::class); + $this->contextProviders = $contextProviders instanceof \Traversable ? iterator_to_array($contextProviders) : $contextProviders; + } + + /** + * @param array $templateContext + * + * @return array + */ + public function provide(array $templateContext, Block $templateBlock): array + { + foreach ($this->contextProviders as $contextProvider) { + if (!$contextProvider->supports($templateBlock)) { + continue; + } + + return $contextProvider->provide($templateContext, $templateBlock); + } + + throw new NoSupportedContextProvider(sprintf('No supported context provider found for block "%s".', $templateBlock->getName())); + } + + public function supports(Block $templateBlock): bool + { + return true; + } +} diff --git a/src/Sylius/Bundle/UiBundle/ContextProvider/ContextProviderInterface.php b/src/Sylius/Bundle/UiBundle/ContextProvider/ContextProviderInterface.php index 8949a78cc5..0963868072 100644 --- a/src/Sylius/Bundle/UiBundle/ContextProvider/ContextProviderInterface.php +++ b/src/Sylius/Bundle/UiBundle/ContextProvider/ContextProviderInterface.php @@ -13,11 +13,11 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\ContextProvider; -use Sylius\Bundle\UiBundle\Registry\TemplateBlock; +use Sylius\Bundle\UiBundle\Registry\Block; interface ContextProviderInterface { - public function provide(array $templateContext, TemplateBlock $templateBlock): array; + public function provide(array $templateContext, Block $templateBlock): array; - public function supports(TemplateBlock $templateBlock): bool; + public function supports(Block $templateBlock): bool; } diff --git a/src/Sylius/Bundle/UiBundle/ContextProvider/DefaultContextProvider.php b/src/Sylius/Bundle/UiBundle/ContextProvider/DefaultContextProvider.php index e18a3fe85f..add91fc431 100644 --- a/src/Sylius/Bundle/UiBundle/ContextProvider/DefaultContextProvider.php +++ b/src/Sylius/Bundle/UiBundle/ContextProvider/DefaultContextProvider.php @@ -13,16 +13,16 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\ContextProvider; -use Sylius\Bundle\UiBundle\Registry\TemplateBlock; +use Sylius\Bundle\UiBundle\Registry\Block; final class DefaultContextProvider implements ContextProviderInterface { - public function provide(array $templateContext, TemplateBlock $templateBlock): array + public function provide(array $templateContext, Block $templateBlock): array { return array_replace($templateBlock->getContext(), $templateContext); } - public function supports(TemplateBlock $templateBlock): bool + public function supports(Block $templateBlock): bool { return true; } diff --git a/src/Sylius/Bundle/UiBundle/ContextProvider/Exception/NoSupportedContextProvider.php b/src/Sylius/Bundle/UiBundle/ContextProvider/Exception/NoSupportedContextProvider.php new file mode 100644 index 0000000000..b2d9535d85 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/ContextProvider/Exception/NoSupportedContextProvider.php @@ -0,0 +1,18 @@ +}> */ + /** @var array}> */ private $renderedEvents = []; - /** @var array}> */ + /** @var array}> */ private array $currentlyRenderedEvents = []; - /** @var array */ + /** @var array */ private array $currentlyRenderedBlocks = []; + /** + * @param array $eventNames + * @param array $context + */ public function startRenderingEvent(array $eventNames, array $context): void { $this->currentlyRenderedEvents[] = ['names' => $eventNames, 'start' => microtime(true), 'blocks' => []]; } - public function startRenderingBlock(TemplateBlock $templateBlock, array $context): void + /** + * @param array $context + */ + public function startRenderingBlock(Block $templateBlock, array $context): void { $this->currentlyRenderedBlocks[] = ['definition' => $templateBlock, 'start' => microtime(true)]; } - public function stopRenderingBlock(TemplateBlock $templateBlock, array $context): void + /** + * @param array $context + */ + public function stopRenderingBlock(Block $templateBlock, array $context): void { $currentlyRenderedBlock = array_pop($this->currentlyRenderedBlocks); $currentlyRenderedBlock['stop'] = microtime(true); @@ -48,6 +58,10 @@ final class TemplateBlockRenderingHistory $this->currentlyRenderedEvents[] = $currentlyRenderedEvent; } + /** + * @param array $eventNames + * @param array $context + */ public function stopRenderingEvent(array $eventNames, array $context): void { $currentlyRenderedEvent = array_pop($this->currentlyRenderedEvents); @@ -56,6 +70,9 @@ final class TemplateBlockRenderingHistory $this->renderedEvents[] = $currentlyRenderedEvent; } + /** + * @return array}> + */ public function getRenderedEvents(): array { return $this->renderedEvents; diff --git a/src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockDataCollector.php b/src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockDataCollector.php index 265a66f6b5..4db87e4d6f 100644 --- a/src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockDataCollector.php +++ b/src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockDataCollector.php @@ -20,7 +20,7 @@ use Symfony\Component\HttpKernel\DataCollector\DataCollector; /** @internal */ final class TemplateBlockDataCollector extends DataCollector { - public function __construct(private TemplateBlockRenderingHistory $templateBlockRenderingHistory) + public function __construct(private BlockRenderingHistory $templateBlockRenderingHistory) { $this->reset(); } diff --git a/src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateBlockRenderer.php b/src/Sylius/Bundle/UiBundle/DataCollector/TraceableBlockRenderer.php similarity index 60% rename from src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateBlockRenderer.php rename to src/Sylius/Bundle/UiBundle/DataCollector/TraceableBlockRenderer.php index b6bd1cbb02..c34670870d 100644 --- a/src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateBlockRenderer.php +++ b/src/Sylius/Bundle/UiBundle/DataCollector/TraceableBlockRenderer.php @@ -13,19 +13,19 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\DataCollector; -use Sylius\Bundle\UiBundle\Registry\TemplateBlock; -use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface; +use Sylius\Bundle\UiBundle\Registry\Block; +use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface; /** @internal */ -final class TraceableTemplateBlockRenderer implements TemplateBlockRendererInterface +final class TraceableBlockRenderer implements BlockRendererInterface { public function __construct( - private TemplateBlockRendererInterface $templateBlockRenderer, - private TemplateBlockRenderingHistory $templateBlockRenderingHistory, + private BlockRendererInterface $templateBlockRenderer, + private BlockRenderingHistory $templateBlockRenderingHistory, ) { } - public function render(TemplateBlock $templateBlock, array $context = []): string + public function render(Block $templateBlock, array $context = []): string { $this->templateBlockRenderingHistory->startRenderingBlock($templateBlock, $context); diff --git a/src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateEventRenderer.php b/src/Sylius/Bundle/UiBundle/DataCollector/TraceableTwigEventRenderer.php similarity index 71% rename from src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateEventRenderer.php rename to src/Sylius/Bundle/UiBundle/DataCollector/TraceableTwigEventRenderer.php index 25296ebee9..02de703a33 100644 --- a/src/Sylius/Bundle/UiBundle/DataCollector/TraceableTemplateEventRenderer.php +++ b/src/Sylius/Bundle/UiBundle/DataCollector/TraceableTwigEventRenderer.php @@ -13,14 +13,14 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\DataCollector; -use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface; +use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface; /** @internal */ -final class TraceableTemplateEventRenderer implements TemplateEventRendererInterface +final class TraceableTwigEventRenderer implements TwigEventRendererInterface { public function __construct( - private TemplateEventRendererInterface $templateEventRenderer, - private TemplateBlockRenderingHistory $templateBlockRenderingHistory, + private TwigEventRendererInterface $templateEventRenderer, + private BlockRenderingHistory $templateBlockRenderingHistory, ) { } diff --git a/src/Sylius/Bundle/UiBundle/DependencyInjection/Compiler/LiveComponentTagPass.php b/src/Sylius/Bundle/UiBundle/DependencyInjection/Compiler/LiveComponentTagPass.php new file mode 100644 index 0000000000..4bbdf88844 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/DependencyInjection/Compiler/LiveComponentTagPass.php @@ -0,0 +1,44 @@ +findTaggedServiceIds('sylius.live_component') as $id => $tags) { + foreach ($tags as $tag) { + $liveComponentService = $container->getDefinition($id); + $liveComponentService->addTag('twig.component', [ + 'key' => $tag['key'] ?? throw new InvalidArgumentException('The "key" attribute is required for the "sylius.live_component" tag'), + 'template' => $tag['template'] ?? throw new InvalidArgumentException('The "template" attribute is required for the "sylius.live_component" tag'), + 'expose_public_props' => $tag['expose_public_props'] ?? true, + 'attributes_var' => $tag['attributes_var'] ?? 'attributes', + 'default_action' => $tag['default_action'] ?? null, + 'live' => true, + 'csrf' => $tag['csrf'] ?? true, + 'route' => $tag['route'] ?? 'ux_live_component', + 'method' => $tag['method'] ?? 'post', + 'url_reference_type' => $tag['url_reference_type'] ?? UrlGeneratorInterface::ABSOLUTE_PATH, + ]); + $liveComponentService->addTag('controller.service_arguments'); + } + } + } +} diff --git a/src/Sylius/Bundle/UiBundle/DependencyInjection/Configuration.php b/src/Sylius/Bundle/UiBundle/DependencyInjection/Configuration.php index fc8ea94709..d86665ec50 100644 --- a/src/Sylius/Bundle/UiBundle/DependencyInjection/Configuration.php +++ b/src/Sylius/Bundle/UiBundle/DependencyInjection/Configuration.php @@ -42,10 +42,32 @@ final class Configuration implements ConfigurationInterface ->ifString() ->then(static fn (?string $template): array => ['template' => $template]) ->end() + ->validate() + ->ifTrue(static function (array $block): bool { + if (!array_key_exists('template', $block) || !array_key_exists('component', $block)) { + return false; + } + + return null !== $block['template'] && [] !== $block['component']; + }) + ->thenInvalid('You cannot use both "template" and "component" for a block.') + ->end() ->children() ->booleanNode('enabled')->defaultNull()->end() ->arrayNode('context')->addDefaultsIfNotSet()->ignoreExtraKeys(false)->end() ->scalarNode('template')->defaultNull()->end() + ->arrayNode('component') + ->beforeNormalization() + ->ifString() + ->then(static fn (?string $component): array => ['name' => $component]) + ->end() + ->treatNullLike([]) + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('name')->isRequired()->end() + ->arrayNode('inputs')->ignoreExtraKeys(false)->end() + ->end() + ->end() ->integerNode('priority')->defaultNull()->end() ; diff --git a/src/Sylius/Bundle/UiBundle/DependencyInjection/SyliusUiExtension.php b/src/Sylius/Bundle/UiBundle/DependencyInjection/SyliusUiExtension.php index ac80e4fc99..d5fbc2ce05 100644 --- a/src/Sylius/Bundle/UiBundle/DependencyInjection/SyliusUiExtension.php +++ b/src/Sylius/Bundle/UiBundle/DependencyInjection/SyliusUiExtension.php @@ -14,8 +14,9 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\DependencyInjection; use Laminas\Stdlib\SplPriorityQueue; +use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface; +use Sylius\Bundle\UiBundle\Registry\ComponentBlock; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; -use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -43,7 +44,7 @@ final class SyliusUiExtension extends Extension */ private function loadEvents(array $eventsConfig, ContainerBuilder $container): void { - $templateBlockRegistryDefinition = $container->findDefinition(TemplateBlockRegistryInterface::class); + $templateBlockRegistryDefinition = $container->findDefinition(BlockRegistryInterface::class); $blocksForEvents = []; foreach ($eventsConfig as $eventName => $eventConfiguration) { @@ -56,19 +57,53 @@ final class SyliusUiExtension extends Extension $blocksPriorityQueue->insert($details, $details['priority'] ?? 0); } + /** @var array{name: string, eventName: string, template: string, component: array{name?: string, inputs?: array}, context: array, priority: int, enabled: bool} $details */ foreach ($blocksPriorityQueue->toArray() as $details) { - /** @var array{name: string, eventName: string, template: string, context: array, priority: int, enabled: bool} $details */ - $blocksForEvents[$eventName][$details['name']] = new Definition(TemplateBlock::class, [ - $details['name'], - $details['eventName'], - $details['template'], - $details['context'], - $details['priority'], - $details['enabled'], - ]); + $blockType = [] !== $details['component'] ? 'component' : 'template'; + $blocksForEvents[$eventName][$details['name']] = match ($blockType) { + 'template' => $this->createTemplateBlockDefinition($details), + 'component' => $this->createComponentBlockDefinition($details), + }; } } $templateBlockRegistryDefinition->setArgument(0, $blocksForEvents); } + + /** + * @param array $details + */ + private function createTemplateBlockDefinition(array $details): Definition + { + return new Definition( + TemplateBlock::class, + [ + $details['name'], + $details['eventName'], + $details['template'], + $details['context'], + $details['priority'], + $details['enabled'], + ], + ); + } + + /** + * @param array $details + */ + private function createComponentBlockDefinition(array $details): Definition + { + return new Definition( + ComponentBlock::class, + [ + $details['name'], + $details['eventName'], + $details['component']['name'], + $details['component']['inputs'] ?? [], + $details['context'], + $details['priority'], + $details['enabled'], + ], + ); + } } diff --git a/src/Sylius/Bundle/UiBundle/Registry/Block.php b/src/Sylius/Bundle/UiBundle/Registry/Block.php new file mode 100644 index 0000000000..4e9ce062c7 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Registry/Block.php @@ -0,0 +1,59 @@ +|null $context + */ + public function __construct( + protected string $name, + protected string $eventName, + protected ?array $context, + protected ?int $priority, + protected ?bool $enabled, + ) { + } + + public function getName(): string + { + return $this->name; + } + + public function getEventName(): string + { + return $this->eventName; + } + + /** + * @return array + */ + public function getContext(): array + { + return $this->context ?? []; + } + + public function getPriority(): int + { + return $this->priority ?? 0; + } + + public function isEnabled(): bool + { + return $this->enabled ?? true; + } + + abstract public function overwriteWith(self $block): self; +} diff --git a/src/Sylius/Bundle/UiBundle/Registry/BlockRegistry.php b/src/Sylius/Bundle/UiBundle/Registry/BlockRegistry.php new file mode 100644 index 0000000000..06239134d1 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Registry/BlockRegistry.php @@ -0,0 +1,90 @@ +> + */ + private array $eventsToBlocks; + + /** + * @param array> $eventsToTemplateBlocks + */ + public function __construct(array $eventsToTemplateBlocks) + { + $this->eventsToBlocks = $eventsToTemplateBlocks; + } + + public function all(): array + { + return $this->eventsToBlocks; + } + + public function findEnabledForEvents(array $eventNames): array + { + // No need to sort blocks again if there's only one event because we have them sorted already + if (count($eventNames) === 1) { + $eventName = reset($eventNames); + + return array_values(array_filter( + $this->eventsToBlocks[$eventName] ?? [], + static fn (Block $block): bool => $block->isEnabled(), + )); + } + + $enabledFinalizedBlocks = array_filter( + $this->findFinalizedForEvents($eventNames), + static fn (Block $block): bool => $block->isEnabled(), + ); + + $blocksPriorityQueue = new SplPriorityQueue(); + foreach ($enabledFinalizedBlocks as $block) { + $blocksPriorityQueue->insert($block, $block->getPriority()); + } + + return $blocksPriorityQueue->toArray(); + } + + /** + * @param string[] $eventNames + * + * @return Block[] + */ + private function findFinalizedForEvents(array $eventNames): array + { + /** @var array $finalizedBlocks */ + $finalizedBlocks = []; + $reversedEventNames = array_reverse($eventNames); + foreach ($reversedEventNames as $eventName) { + $blocks = $this->eventsToBlocks[$eventName] ?? []; + foreach ($blocks as $blockName => $block) { + if (array_key_exists($blockName, $finalizedBlocks)) { + $block = $finalizedBlocks[$blockName]->overwriteWith($block); + } + + $finalizedBlocks[$blockName] = $block; + } + } + + return $finalizedBlocks; + } +} + +class_alias(BlockRegistry::class, '\Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistry'); diff --git a/src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistryInterface.php b/src/Sylius/Bundle/UiBundle/Registry/BlockRegistryInterface.php similarity index 63% rename from src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistryInterface.php rename to src/Sylius/Bundle/UiBundle/Registry/BlockRegistryInterface.php index ff320034be..a69c409066 100644 --- a/src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistryInterface.php +++ b/src/Sylius/Bundle/UiBundle/Registry/BlockRegistryInterface.php @@ -13,17 +13,19 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Registry; -interface TemplateBlockRegistryInterface +interface BlockRegistryInterface { /** - * @return array> + * @return array> */ public function all(): array; /** - * @param non-empty-list $eventNames + * @param string[] $eventNames * - * @return TemplateBlock[] + * @return Block[] */ public function findEnabledForEvents(array $eventNames): array; } + +class_alias(BlockRegistryInterface::class, '\Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface'); diff --git a/src/Sylius/Bundle/UiBundle/Registry/ComponentBlock.php b/src/Sylius/Bundle/UiBundle/Registry/ComponentBlock.php new file mode 100644 index 0000000000..33fb1431cb --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Registry/ComponentBlock.php @@ -0,0 +1,73 @@ + $componentInputs + * @param array|null $context + */ + public function __construct( + string $name, + string $eventName, + private string $componentName, + private array $componentInputs, + ?array $context, + ?int $priority, + ?bool $enabled, + ) { + parent::__construct($name, $eventName, $context, $priority, $enabled); + } + + public function getComponentName(): string + { + return $this->componentName; + } + + /** @return array */ + public function getComponentInputs(): array + { + return $this->componentInputs; + } + + public function overwriteWith(Block $block): self + { + if (!$block instanceof self) { + throw new \DomainException(sprintf( + 'Trying to overwrite component block "%s" with block of different type "%s".', + $this->name, + get_class($block), + )); + } + + if ($this->name !== $block->name) { + throw new \DomainException(sprintf( + 'Trying to overwrite block "%s" with block "%s".', + $this->name, + $block->name, + )); + } + + return new self( + $this->name, + $block->eventName, + $block->getComponentName(), + $block->getComponentInputs(), + $block->context ?? $this->context, + $block->priority ?? $this->priority, + $block->enabled ?? $this->enabled, + ); + } +} diff --git a/src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php b/src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php index 256dc91f1c..ca07f7b42d 100644 --- a/src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php +++ b/src/Sylius/Bundle/UiBundle/Registry/TemplateBlock.php @@ -13,26 +13,17 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Registry; -final class TemplateBlock +final class TemplateBlock extends Block { public function __construct( - private string $name, - private string $eventName, + string $name, + string $eventName, private ?string $template, - private ?array $context, - private ?int $priority, - private ?bool $enabled, + ?array $context, + ?int $priority, + ?bool $enabled, ) { - } - - public function getName(): string - { - return $this->name; - } - - public function getEventName(): string - { - return $this->eventName; + parent::__construct($name, $eventName, $context, $priority, $enabled); } public function getTemplate(): string @@ -48,23 +39,16 @@ final class TemplateBlock return $this->template; } - public function getContext(): array + public function overwriteWith(Block $block): self { - return $this->context ?? []; - } + if (!$block instanceof self) { + throw new \DomainException(sprintf( + 'Trying to overwrite template block "%s" with block of different type "%s".', + $this->name, + get_class($block), + )); + } - public function getPriority(): int - { - return $this->priority ?? 0; - } - - public function isEnabled(): bool - { - return $this->enabled ?? true; - } - - public function overwriteWith(self $block): self - { if ($this->name !== $block->name) { throw new \DomainException(sprintf( 'Trying to overwrite block "%s" with block "%s".', diff --git a/src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistry.php b/src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistry.php deleted file mode 100644 index 00929eac7a..0000000000 --- a/src/Sylius/Bundle/UiBundle/Registry/TemplateBlockRegistry.php +++ /dev/null @@ -1,85 +0,0 @@ -> - */ - private $eventsToTemplateBlocks; - - public function __construct(array $eventsToTemplateBlocks) - { - $this->eventsToTemplateBlocks = $eventsToTemplateBlocks; - } - - public function all(): array - { - return $this->eventsToTemplateBlocks; - } - - public function findEnabledForEvents(array $eventNames): array - { - // No need to sort blocks again if there's only one event because we have them sorted already - if (count($eventNames) === 1) { - $eventName = reset($eventNames); - - return array_values(array_filter( - $this->eventsToTemplateBlocks[$eventName] ?? [], - static fn (TemplateBlock $templateBlock): bool => $templateBlock->isEnabled(), - )); - } - - $enabledFinalizedTemplateBlocks = array_filter( - $this->findFinalizedForEvents($eventNames), - static fn (TemplateBlock $templateBlock): bool => $templateBlock->isEnabled(), - ); - - $templateBlocksPriorityQueue = new SplPriorityQueue(); - foreach ($enabledFinalizedTemplateBlocks as $templateBlock) { - $templateBlocksPriorityQueue->insert($templateBlock, $templateBlock->getPriority()); - } - - return $templateBlocksPriorityQueue->toArray(); - } - - /** - * @param non-empty-list $eventNames - * - * @return TemplateBlock[] - */ - private function findFinalizedForEvents(array $eventNames): array - { - /** @var array $finalizedTemplateBlocks */ - $finalizedTemplateBlocks = []; - $reversedEventNames = array_reverse($eventNames); - foreach ($reversedEventNames as $eventName) { - $templateBlocks = $this->eventsToTemplateBlocks[$eventName] ?? []; - foreach ($templateBlocks as $blockName => $templateBlock) { - if (array_key_exists($blockName, $finalizedTemplateBlocks)) { - $templateBlock = $finalizedTemplateBlocks[$blockName]->overwriteWith($templateBlock); - } - - $finalizedTemplateBlocks[$blockName] = $templateBlock; - } - } - - return $finalizedTemplateBlocks; - } -} diff --git a/src/Sylius/Bundle/UiBundle/Renderer/BlockRendererInterface.php b/src/Sylius/Bundle/UiBundle/Renderer/BlockRendererInterface.php new file mode 100644 index 0000000000..968f537be1 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Renderer/BlockRendererInterface.php @@ -0,0 +1,26 @@ + $context + */ + public function render(Block $templateBlock, array $context = []): string; +} + +class_alias(BlockRendererInterface::class, '\Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface'); diff --git a/src/Sylius/Bundle/UiBundle/Renderer/CompositeBlockRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/CompositeBlockRenderer.php new file mode 100644 index 0000000000..19053362ea --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Renderer/CompositeBlockRenderer.php @@ -0,0 +1,47 @@ + */ + private array $blockRenderers; + + /** + * @param iterable $blockRenderers + */ + public function __construct(iterable $blockRenderers) + { + Assert::allIsInstanceOf($blockRenderers, SupportableBlockRendererInterface::class); + $this->blockRenderers = $blockRenderers instanceof \Traversable ? iterator_to_array($blockRenderers) : $blockRenderers; + } + + public function render(Block $templateBlock, array $context = []): string + { + foreach ($this->blockRenderers as $blockRenderer) { + if (!$blockRenderer->supports($templateBlock)) { + continue; + } + + return $blockRenderer->render($templateBlock, $context); + } + + throw new NoSupportedBlockRenderer(sprintf('No supported block renderer found for "%s" block.', $templateBlock->getName())); + } +} diff --git a/src/Sylius/Bundle/UiBundle/Renderer/DelegatingTemplateEventRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/DelegatingTwigEventRenderer.php similarity index 65% rename from src/Sylius/Bundle/UiBundle/Renderer/DelegatingTemplateEventRenderer.php rename to src/Sylius/Bundle/UiBundle/Renderer/DelegatingTwigEventRenderer.php index 91bac0dfd7..a8e1becefe 100644 --- a/src/Sylius/Bundle/UiBundle/Renderer/DelegatingTemplateEventRenderer.php +++ b/src/Sylius/Bundle/UiBundle/Renderer/DelegatingTwigEventRenderer.php @@ -13,14 +13,18 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Renderer; -use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface; +use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface; -final class DelegatingTemplateEventRenderer implements TemplateEventRendererInterface +final class DelegatingTwigEventRenderer implements TwigEventRendererInterface { - public function __construct(private TemplateBlockRegistryInterface $templateBlockRegistry, private TemplateBlockRendererInterface $templateBlockRenderer) + public function __construct(private BlockRegistryInterface $templateBlockRegistry, private BlockRendererInterface $templateBlockRenderer) { } + /** + * @param array $eventNames + * @param array $context + */ public function render(array $eventNames, array $context = []): string { $templateBlocks = $this->templateBlockRegistry->findEnabledForEvents($eventNames); diff --git a/src/Sylius/Bundle/UiBundle/Renderer/Exception/NoSupportedBlockRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/Exception/NoSupportedBlockRenderer.php new file mode 100644 index 0000000000..35f02a224c --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Renderer/Exception/NoSupportedBlockRenderer.php @@ -0,0 +1,18 @@ +shouldRenderHtmlDebug($templateBlock)) { + return $this->blockRenderer->render($templateBlock, $context); + } + + $renderedParts = []; + + switch (get_class($templateBlock)) { + case TemplateBlock::class: + $renderedParts[] = $this->getBeginBlockForTemplate($templateBlock); + + break; + case ComponentBlock::class: + $renderedParts[] = $this->getBeginBlockForComponent($templateBlock); + + break; + } + + $renderedParts[] = $this->blockRenderer->render($templateBlock, $context); + $renderedParts[] = $this->getEndBlock($templateBlock); + + return implode("\n", $renderedParts); + } + + private function shouldRenderHtmlDebug(Block $block): bool + { + return match (get_class($block)) { + TemplateBlock::class => strrpos($block->getTemplate(), '.html.twig') !== false, + ComponentBlock::class => true, + default => false, + }; + } + + private function getBeginBlockForTemplate(Block $block): string + { + if (!$block instanceof TemplateBlock) { + throw new \InvalidArgumentException(sprintf('Block must be instance of "%s"', TemplateBlock::class)); + } + + return sprintf( + '', + $block->getEventName(), + $block->getName(), + $block->getTemplate(), + $block->getPriority(), + ); + } + + private function getBeginBlockForComponent(Block $block): string + { + if (!$block instanceof ComponentBlock) { + throw new \InvalidArgumentException(sprintf('Block must be instance of "%s"', ComponentBlock::class)); + } + + return sprintf( + '', + $block->getEventName(), + $block->getName(), + $block->getComponentName(), + $block->getPriority(), + ); + } + + private function getEndBlock(Block $templateBlock): string + { + return sprintf( + '', + $templateBlock->getEventName(), + $templateBlock->getName(), + ); + } +} + +class_alias(HtmlDebugBlockRenderer::class, '\Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateBlockRenderer'); diff --git a/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateBlockRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateBlockRenderer.php deleted file mode 100644 index 677a1ab141..0000000000 --- a/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateBlockRenderer.php +++ /dev/null @@ -1,52 +0,0 @@ -getTemplate(), '.html.twig') !== false; - - $renderedParts = []; - - if ($shouldRenderHtmlDebug) { - $renderedParts[] = sprintf( - '', - $templateBlock->getEventName(), - $templateBlock->getName(), - $templateBlock->getTemplate(), - $templateBlock->getPriority(), - ); - } - - $renderedParts[] = $this->templateBlockRenderer->render($templateBlock, $context); - - if ($shouldRenderHtmlDebug) { - $renderedParts[] = sprintf( - '', - $templateBlock->getEventName(), - $templateBlock->getName(), - ); - } - - return implode("\n", $renderedParts); - } -} diff --git a/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateEventRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateEventRenderer.php deleted file mode 100644 index 273e9eca1c..0000000000 --- a/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTemplateEventRenderer.php +++ /dev/null @@ -1,59 +0,0 @@ -shouldRenderHtmlDebug($this->templateBlockRegistry->findEnabledForEvents($eventNames)); - - $renderedParts = []; - - if ($shouldRenderHtmlDebug) { - $renderedParts[] = sprintf( - '', - implode(', ', $eventNames), - ); - } - - $renderedParts[] = $this->templateEventRenderer->render($eventNames, $context); - - if ($shouldRenderHtmlDebug) { - $renderedParts[] = sprintf( - '', - implode(', ', $eventNames), - ); - } - - return implode("\n", $renderedParts); - } - - /** - * @param TemplateBlock[] $templateBlocks - */ - private function shouldRenderHtmlDebug(array $templateBlocks): bool - { - return count($templateBlocks) === 0 || count(array_filter($templateBlocks, static fn (TemplateBlock $templateBlock): bool => strrpos($templateBlock->getTemplate(), '.html.twig') !== false)) >= 1; - } -} diff --git a/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTwigEventRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTwigEventRenderer.php new file mode 100644 index 0000000000..41dbdfd8a2 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugTwigEventRenderer.php @@ -0,0 +1,79 @@ + $eventNames + * @param array $context + */ + public function render(array $eventNames, array $context = []): string + { + $shouldRenderHtmlDebug = $this->shouldRenderHtmlDebug($this->blockRegistry->findEnabledForEvents($eventNames)); + + $renderedParts = []; + + if ($shouldRenderHtmlDebug) { + $renderedParts[] = sprintf( + '', + implode(', ', $eventNames), + ); + } + + $renderedParts[] = $this->templateEventRenderer->render($eventNames, $context); + + if ($shouldRenderHtmlDebug) { + $renderedParts[] = sprintf( + '', + implode(', ', $eventNames), + ); + } + + return implode("\n", $renderedParts); + } + + /** + * @param Block[] $blocks + */ + private function shouldRenderHtmlDebug(array $blocks): bool + { + if (0 === count($blocks)) { + return true; + } + + return 0 !== count( + array_filter($blocks, function (Block $block): bool { + return match (get_class($block)) { + TemplateBlock::class => strrpos($block->getTemplate(), '.html.twig') !== false, + ComponentBlock::class => true, + default => false, + }; + }), + ); + } +} + +class_alias(HtmlDebugTwigEventRenderer::class, '\Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateEventRenderer'); diff --git a/src/Sylius/Bundle/UiBundle/Renderer/TemplateBlockRendererInterface.php b/src/Sylius/Bundle/UiBundle/Renderer/SupportableBlockRendererInterface.php similarity index 61% rename from src/Sylius/Bundle/UiBundle/Renderer/TemplateBlockRendererInterface.php rename to src/Sylius/Bundle/UiBundle/Renderer/SupportableBlockRendererInterface.php index 6e3c6ea86f..6cee458027 100644 --- a/src/Sylius/Bundle/UiBundle/Renderer/TemplateBlockRendererInterface.php +++ b/src/Sylius/Bundle/UiBundle/Renderer/SupportableBlockRendererInterface.php @@ -13,9 +13,9 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Renderer; -use Sylius\Bundle\UiBundle\Registry\TemplateBlock; +use Sylius\Bundle\UiBundle\Registry\Block; -interface TemplateBlockRendererInterface +interface SupportableBlockRendererInterface extends BlockRendererInterface { - public function render(TemplateBlock $templateBlock, array $context = []): string; + public function supports(Block $block): bool; } diff --git a/src/Sylius/Bundle/UiBundle/Renderer/TwigComponentBlockRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/TwigComponentBlockRenderer.php new file mode 100644 index 0000000000..38a8762229 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Renderer/TwigComponentBlockRenderer.php @@ -0,0 +1,84 @@ + $context + */ + public function render(Block $templateBlock, array $context = []): string + { + if (!$this->supports($templateBlock)) { + throw new \InvalidArgumentException(sprintf( + 'Block "%s" is not supported by "%s".', + $templateBlock->getName(), + self::class, + )); + } + + $context = $this->contextProvider->provide($context, $templateBlock); + + $inputs = $this->mapArrayRecursively(function (mixed $value) use ($context) { + if (!is_string($value)) { + return $value; + } + + if (!str_starts_with($value, 'expr:')) { + return $value; + } + + return $this->expressionLanguage->evaluate(substr($value, 5), ['context' => $context]); + }, $templateBlock->getComponentInputs()); + + return $this->componentRenderer->createAndRender($templateBlock->getComponentName(), $inputs); + } + + /** + * @param array $array + * + * @return array + */ + private function mapArrayRecursively(callable $callback, array $array): array + { + $result = []; + foreach ($array as $key => $value) { + $result[$key] = is_array($value) + ? $this->mapArrayRecursively($callback, $value) + : $callback($value); + } + + return $result; + } + + public function supports(Block $block): bool + { + return is_a($block, ComponentBlock::class); + } +} diff --git a/src/Sylius/Bundle/UiBundle/Renderer/TemplateEventRendererInterface.php b/src/Sylius/Bundle/UiBundle/Renderer/TwigEventRendererInterface.php similarity index 68% rename from src/Sylius/Bundle/UiBundle/Renderer/TemplateEventRendererInterface.php rename to src/Sylius/Bundle/UiBundle/Renderer/TwigEventRendererInterface.php index 801d393c59..0f8b6e4d3b 100644 --- a/src/Sylius/Bundle/UiBundle/Renderer/TemplateEventRendererInterface.php +++ b/src/Sylius/Bundle/UiBundle/Renderer/TwigEventRendererInterface.php @@ -13,10 +13,13 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Renderer; -interface TemplateEventRendererInterface +interface TwigEventRendererInterface { /** * @param non-empty-list $eventNames + * @param array $context */ public function render(array $eventNames, array $context = []): string; } + +class_alias(TwigEventRendererInterface::class, '\Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface'); diff --git a/src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php b/src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php index ddd43d61be..681acbb2fa 100644 --- a/src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php +++ b/src/Sylius/Bundle/UiBundle/Renderer/TwigTemplateBlockRenderer.php @@ -14,17 +14,32 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Renderer; use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface; +use Sylius\Bundle\UiBundle\Registry\Block; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; use Twig\Environment; -final class TwigTemplateBlockRenderer implements TemplateBlockRendererInterface +final class TwigTemplateBlockRenderer implements SupportableBlockRendererInterface { + /** + * @param iterable $contextProviders + */ public function __construct(private Environment $twig, private iterable $contextProviders) { } - public function render(TemplateBlock $templateBlock, array $context = []): string + /** + * @param TemplateBlock $templateBlock + */ + public function render(Block $templateBlock, array $context = []): string { + if (!$this->supports($templateBlock)) { + throw new \InvalidArgumentException(sprintf( + 'Block "%s" is not supported by "%s".', + $templateBlock->getName(), + self::class, + )); + } + foreach ($this->contextProviders as $contextProvider) { if (!$contextProvider instanceof ContextProviderInterface || !$contextProvider->supports($templateBlock)) { continue; @@ -35,4 +50,9 @@ final class TwigTemplateBlockRenderer implements TemplateBlockRendererInterface return $this->twig->render($templateBlock->getTemplate(), $context); } + + public function supports(Block $block): bool + { + return is_a($block, TemplateBlock::class); + } } diff --git a/src/Sylius/Bundle/UiBundle/Resources/config/services/debug/template_event.xml b/src/Sylius/Bundle/UiBundle/Resources/config/services/debug/template_event.xml index fdb8b75072..f52220ead8 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/config/services/debug/template_event.xml +++ b/src/Sylius/Bundle/UiBundle/Resources/config/services/debug/template_event.xml @@ -13,30 +13,33 @@ - + - + - - - + + + + + + + + + - - - + + + - - - - - - + + + diff --git a/src/Sylius/Bundle/UiBundle/Resources/config/services/template_event.xml b/src/Sylius/Bundle/UiBundle/Resources/config/services/template_event.xml index 0647e753df..ab5bb3277c 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/config/services/template_event.xml +++ b/src/Sylius/Bundle/UiBundle/Resources/config/services/template_event.xml @@ -13,19 +13,36 @@ - + + + + + + - + + + + + + + + + + + + - + - + + diff --git a/src/Sylius/Bundle/UiBundle/Resources/config/services/twig.xml b/src/Sylius/Bundle/UiBundle/Resources/config/services/twig.xml index 5086735370..4ee6cd1659 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/config/services/twig.xml +++ b/src/Sylius/Bundle/UiBundle/Resources/config/services/twig.xml @@ -21,11 +21,13 @@ %kernel.environment% + %kernel.debug% %kernel.environment% + %kernel.debug% diff --git a/src/Sylius/Bundle/UiBundle/Resources/translations/messages.en.yml b/src/Sylius/Bundle/UiBundle/Resources/translations/messages.en.yml index df4b788895..3a51e95743 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/translations/messages.en.yml +++ b/src/Sylius/Bundle/UiBundle/Resources/translations/messages.en.yml @@ -38,6 +38,7 @@ sylius: add_new_role: 'Add new role' add_province: 'Add province' add_rule: 'Add rule' + add_scope: 'Add scope' add_to_cart: 'Add to cart' add_value: 'Add value' add_your_review: 'Add your review' @@ -47,6 +48,7 @@ sylius: additional_information: 'Additional information' address: 'Address' address_book: 'Address book' + addresses: 'Addresses' addressing: 'Addressing' addressing_step: 'Addressing step' adjustments: 'Adjustments' @@ -156,6 +158,7 @@ sylius: content: 'Content' countries: 'Countries' country: 'Country' + country_code: 'Country code' country_details: 'Country details' coupon: 'Coupon' coupon_based: 'Coupon based' @@ -218,6 +221,7 @@ sylius: customer_can_login_to_the_store: 'Customer can login to the store?' customer_care: 'Customer Care' customer_details: 'Customer details' + customer_group: 'Customer group' customer_groups: 'Customer groups' customer_id: 'Customer ID' customer_login: 'Customer login' @@ -446,6 +450,7 @@ sylius: login: 'Login' login_button: 'Login' login_sylius_store: 'Login Sylius store' + login_to_your_account: 'Login to your account' logout: 'Logout' look_and_feel: 'Look & feel' lowest_price_before_discount: 'Lowest price before discount' @@ -644,6 +649,7 @@ sylius: percentage_discount: 'Percentage discount' permissions: 'Permissions' personal_information: 'Personal information' + phone: 'Phone' phone_number: 'Phone number' place_order: 'Place order' placed_an_order: 'You have successfully placed an order.' @@ -665,6 +671,7 @@ sylius: product: 'Product' product_association_index: 'Association' product_association_type_index: 'Association type' + product_association_type: 'Product association type' product_association_types: 'Product association types' product_associations: 'Product associations' product_attributes: 'Product attributes' @@ -681,6 +688,7 @@ sylius: products_categorized_under_taxon_taxon: 'Products Categorized under "%taxon%" taxon' products_index_of_all_products_in_your_store: 'Products Index of all products in your store' profile: 'Profile' + promotion: 'Cart promotion' promotion_configuration: 'Promotion configuration' promotion_coupons: 'Coupons' promotion_details: 'Promotion details' @@ -690,6 +698,8 @@ sylius: promotions: 'Cart promotions' properties: 'Properties' province: 'Province' + province_code: 'Province code' + province_name: 'Province name' provinces: 'Provinces' purchased_from: 'Purchased from' qty: 'Qty' @@ -717,6 +727,7 @@ sylius: remember_me: 'Remember me' remove_attribute: 'Remove attribute' repeat_new_password: 'Repeat new password' + report_an_issue: 'Report an issue' report_details: 'Report details' report_it: 'Report it' reports: 'Reports' @@ -831,6 +842,7 @@ sylius: tax_categories: 'Tax Categories' tax_category: 'Tax category' tax_rate_details: 'Tax rate details' + tax_rate: 'Tax Rate' tax_rates: 'Tax Rates' tax_total: 'Tax total' taxation_categories: 'Taxation categories' diff --git a/src/Sylius/Bundle/UiBundle/Resources/views/DataCollector/templateBlock.html.twig b/src/Sylius/Bundle/UiBundle/Resources/views/DataCollector/templateBlock.html.twig index 8820aec5ef..32eb3d3a90 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/views/DataCollector/templateBlock.html.twig +++ b/src/Sylius/Bundle/UiBundle/Resources/views/DataCollector/templateBlock.html.twig @@ -80,7 +80,8 @@ {% if event.names|length > 1 %}Origin event{% endif %} Name - Template + Type + Path Duration Priority @@ -88,7 +89,8 @@ {% if event.names|length > 1 %}{{ block.definition.eventName }}{% endif %} {{ block.definition.name }} - {{ block.definition.template }} + {{ block.definition.component != [] ? 'Component' : 'Template' }} + {{ block.definition.component ?? block.definition.template }} {{ '%.0f'|format(block.time * 1000) }}ms {{ block.definition.priority }} diff --git a/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/nameAndDescription.html.twig b/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/nameAndDescription.html.twig index fd7f89c650..43f92e3c31 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/nameAndDescription.html.twig +++ b/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/nameAndDescription.html.twig @@ -1,4 +1,6 @@ {{ data.name }} {% if data.description is not empty %} -

    {{ data.description }}

    +
    + {{ data.description }} +
    {% endif %} diff --git a/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/position.html.twig b/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/position.html.twig index ec409b9524..aac977dd11 100644 --- a/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/position.html.twig +++ b/src/Sylius/Bundle/UiBundle/Resources/views/Grid/Field/position.html.twig @@ -1 +1 @@ -
    {{ data }}
    +{{ data }} diff --git a/src/Sylius/Bundle/UiBundle/SyliusUiBundle.php b/src/Sylius/Bundle/UiBundle/SyliusUiBundle.php index 63a1a41515..345e3cf916 100644 --- a/src/Sylius/Bundle/UiBundle/SyliusUiBundle.php +++ b/src/Sylius/Bundle/UiBundle/SyliusUiBundle.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle; use Sylius\Bundle\UiBundle\DependencyInjection\Compiler\LegacySonataBlockPass; +use Sylius\Bundle\UiBundle\DependencyInjection\Compiler\LiveComponentTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -25,5 +26,6 @@ final class SyliusUiBundle extends Bundle public function build(ContainerBuilder $container): void { $container->addCompilerPass(new LegacySonataBlockPass()); + $container->addCompilerPass(new LiveComponentTagPass(), priority: 500); } } diff --git a/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/Compiler/LiveComponentTagPassTest.php b/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/Compiler/LiveComponentTagPassTest.php new file mode 100644 index 0000000000..f4a4fc7eab --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/Compiler/LiveComponentTagPassTest.php @@ -0,0 +1,119 @@ +addTag('sylius.live_component', ['key' => 'foo', 'template' => 'bar']); + + $this->setDefinition('my_live_component', $liveComponent); + + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithTag( + 'my_live_component', + 'twig.component', + [ + 'key' => 'foo', + 'template' => 'bar', + 'expose_public_props' => true, + 'attributes_var' => 'attributes', + 'default_action' => null, + 'live' => true, + 'csrf' => true, + 'route' => 'ux_live_component', + 'method' => 'post', + 'url_reference_type' => UrlGeneratorInterface::ABSOLUTE_PATH, + ] + ); + $this->assertContainerBuilderHasServiceDefinitionWithTag('my_live_component', 'controller.service_arguments'); + } + + public function testOverridingTagAttributesWithLiveComponentTag(): void + { + $liveComponent = new Definition(); + $liveComponent->addTag('sylius.live_component', [ + 'key' => 'foo', + 'template' => 'bar', + 'expose_public_props' => false, + 'attributes_var' => 'custom_attributes', + 'default_action' => 'customAction', + 'csrf' => false, + 'route' => 'custom_route', + 'method' => 'get', + 'url_reference_type' => UrlGeneratorInterface::ABSOLUTE_URL, + ]); + + $this->setDefinition('my_live_component', $liveComponent); + + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithTag( + 'my_live_component', + 'twig.component', + [ + 'key' => 'foo', + 'template' => 'bar', + 'expose_public_props' => false, + 'attributes_var' => 'custom_attributes', + 'default_action' => 'customAction', + 'live' => true, + 'csrf' => false, + 'route' => 'custom_route', + 'method' => 'get', + 'url_reference_type' => UrlGeneratorInterface::ABSOLUTE_URL, + ] + ); + } + + public function testThrowingExceptionWhenKeyIsNotPresentOnLiveComponentTag(): void + { + $liveComponent = new Definition(); + $liveComponent->addTag('sylius.live_component', ['template' => 'bar']); + + $this->setDefinition('my_live_component', $liveComponent); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The "key" attribute is required for the "sylius.live_component" tag'); + + $this->compile(); + } + + public function testThrowingExceptionWhenTemplateIsNotPresentOnLiveComponentTag(): void + { + $liveComponent = new Definition(); + $liveComponent->addTag('sylius.live_component', ['key' => 'foo']); + + $this->setDefinition('my_live_component', $liveComponent); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The "template" attribute is required for the "sylius.live_component" tag'); + + $this->compile(); + } + + protected function registerCompilerPass(ContainerBuilder $container): void + { + $container->addCompilerPass(new LiveComponentTagPass()); + } +} diff --git a/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/ConfigurationTest.php index 357a81b3b4..f440301034 100644 --- a/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -213,6 +213,108 @@ final class ConfigurationTest extends TestCase ); } + /** @test */ + public function component_block_configuration_can_be_shortened_to_template_string_only(): void + { + $this->assertProcessedConfigurationEquals( + [ + [ + 'events' => [ + 'event_name' => [ + 'blocks' => [ + 'block_name' => [ + 'component' => 'component_name', + ], + ], + ], + ], + ], + ], + [ + 'events' => [ + 'event_name' => [ + 'blocks' => [ + 'block_name' => [ + 'component' => [ + 'name' => 'component_name', + ], + ], + ], + ], + ], + ], + 'events.*.blocks.*.component', + ); + } + + /** @test */ + public function component_block_configuration_can_be_defined_with_inputs(): void + { + $this->assertProcessedConfigurationEquals( + [ + [ + 'events' => [ + 'event_name' => [ + 'blocks' => [ + 'block_name' => [ + 'component' => [ + 'name' => 'component_name', + 'inputs' => [ + 'foo' => 'bar', + 'bar' => 'baz', + ], + ], + ], + ], + ], + ], + ], + ], + [ + 'events' => [ + 'event_name' => [ + 'blocks' => [ + 'block_name' => [ + 'component' => [ + 'name' => 'component_name', + 'inputs' => [ + 'foo' => 'bar', + 'bar' => 'baz', + ], + ], + ], + ], + ], + ], + ], + 'events.*.blocks.*.component', + ); + } + + /** @test */ + public function template_and_component_cannot_be_defined_at_the_same_time(): void + { + $this->assertPartialConfigurationIsInvalid( + [ + [ + 'events' => [ + 'event_name' => [ + 'blocks' => [ + 'block_name' => [ + 'template' => 'template.html.twig', + 'component' => [ + 'name' => 'component_name', + ], + ], + ], + ], + ], + ], + ], + 'events.*.blocks.*.template', + ); + } + protected function getConfiguration(): ConfigurationInterface { return new Configuration(); diff --git a/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/SyliusUiExtensionTest.php b/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/SyliusUiExtensionTest.php index 9d66309240..0632e0c9d6 100644 --- a/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/SyliusUiExtensionTest.php +++ b/src/Sylius/Bundle/UiBundle/Tests/DependencyInjection/SyliusUiExtensionTest.php @@ -15,8 +15,9 @@ namespace Sylius\Bundle\UiBundle\Tests\DependencyInjection; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase; use Sylius\Bundle\UiBundle\DependencyInjection\SyliusUiExtension; +use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface; +use Sylius\Bundle\UiBundle\Registry\ComponentBlock; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; -use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface; use Symfony\Component\DependencyInjection\Definition; final class SyliusUiExtensionTest extends AbstractExtensionTestCase @@ -30,6 +31,7 @@ final class SyliusUiExtensionTest extends AbstractExtensionTestCase 'first_event' => ['blocks' => [ 'first_block' => ['template' => 'first.html.twig', 'context' => [], 'enabled' => true, 'priority' => 0], 'second_block' => ['template' => 'second.html.twig', 'context' => ['foo' => 'bar'], 'enabled' => true, 'priority' => 0], + 'third_block' => ['component' => 'component_name', 'context' => [], 'enabled' => true, 'priority' => 0], ]], 'second_event' => ['blocks' => [ 'another_block' => ['template' => 'another.html.twig', 'context' => [], 'enabled' => true, 'priority' => 0], @@ -37,12 +39,13 @@ final class SyliusUiExtensionTest extends AbstractExtensionTestCase ]]); $this->assertContainerBuilderHasServiceDefinitionWithArgument( - TemplateBlockRegistryInterface::class, + BlockRegistryInterface::class, 0, [ 'first_event' => [ 'first_block' => new Definition(TemplateBlock::class, ['first_block', 'first_event', 'first.html.twig', [], 0, true]), 'second_block' => new Definition(TemplateBlock::class, ['second_block', 'first_event', 'second.html.twig', ['foo' => 'bar'], 0, true]), + 'third_block' => new Definition(ComponentBlock::class, ['third_block', 'first_event', 'component_name', [], [], 0, true]), ], 'second_event' => [ 'another_block' => new Definition(TemplateBlock::class, ['another_block', 'second_event', 'another.html.twig', [], 0, true]), @@ -66,7 +69,7 @@ final class SyliusUiExtensionTest extends AbstractExtensionTestCase ]]); $this->assertContainerBuilderHasServiceDefinitionWithArgument( - TemplateBlockRegistryInterface::class, + BlockRegistryInterface::class, 0, ['event_name' => [ 'first_block' => new Definition(TemplateBlock::class, ['first_block', 'event_name', 'first.html.twig', [], 5, true]), diff --git a/src/Sylius/Bundle/UiBundle/Tests/Functional/Kernel.php b/src/Sylius/Bundle/UiBundle/Tests/Functional/Kernel.php index d77d75743a..648301fb42 100644 --- a/src/Sylius/Bundle/UiBundle/Tests/Functional/Kernel.php +++ b/src/Sylius/Bundle/UiBundle/Tests/Functional/Kernel.php @@ -16,12 +16,14 @@ namespace Sylius\Bundle\UiBundle\Tests\Functional; use Sonata\BlockBundle\SonataBlockBundle; use Sylius\Bundle\UiBundle\SyliusUiBundle; use Sylius\Bundle\UiBundle\Tests\Functional\src\CustomContextProvider; +use Sylius\Bundle\UiBundle\Tests\Functional\src\SomeTwigComponent; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as HttpKernel; +use Symfony\UX\TwigComponent\TwigComponentBundle; use Symfony\WebpackEncoreBundle\WebpackEncoreBundle; final class Kernel extends HttpKernel @@ -37,6 +39,7 @@ final class Kernel extends HttpKernel new SonataBlockBundle(), new SyliusUiBundle(), new WebpackEncoreBundle(), + new TwigComponentBundle(), ]; } @@ -44,6 +47,8 @@ final class Kernel extends HttpKernel { $container->register(CustomContextProvider::class)->addTag('sylius.ui.template_event.context_provider'); + $container->register(SomeTwigComponent::class)->addTag('twig.component', ['template' => 'blocks/twigComponent/someTwigComponent.html.twig']); + $container->loadFromExtension('framework', [ 'secret' => 'S0ME_SECRET', ]); @@ -117,6 +122,25 @@ final class Kernel extends HttpKernel ], ], ], + 'template_event' => [ + 'blocks' => [ + 'block' => [ + 'component' => 'SomeTwigComponent', + ], + ], + ], + 'template_event_with_context' => [ + 'blocks' => [ + 'block' => [ + 'component' => [ + 'name' => 'SomeTwigComponent', + 'inputs' => [ + 'context' => 'expr:context', + ], + ], + ], + ], + ], ]]); $container->loadFromExtension('webpack_encore', [ diff --git a/src/Sylius/Bundle/UiBundle/Tests/Functional/TemplateEventTest.php b/src/Sylius/Bundle/UiBundle/Tests/Functional/TemplateEventTest.php index c9455a784e..6acb7949b0 100644 --- a/src/Sylius/Bundle/UiBundle/Tests/Functional/TemplateEventTest.php +++ b/src/Sylius/Bundle/UiBundle/Tests/Functional/TemplateEventTest.php @@ -100,4 +100,27 @@ final class TemplateEventTest extends KernelTestCase Assert::assertSame($expectedLines, $renderedLines); } + + /** @test */ + public function it_renders_component(): void + { + $expectedLines = [ + '', + '', + 'Hello from the Twig Component :)', + 'Context: no context', + '', + '', + '', + '', + 'Hello from the Twig Component :)', + 'Context: foo=bar', + '', + '', + ]; + + $renderedLines = array_values(array_filter(explode("\n", $this->twig->render('templateEventsButComponent.txt.twig')))); + + Assert::assertSame($expectedLines, $renderedLines); + } } diff --git a/src/Sylius/Bundle/UiBundle/Tests/Functional/src/CustomContextProvider.php b/src/Sylius/Bundle/UiBundle/Tests/Functional/src/CustomContextProvider.php index 3250e3529a..2aba9c6afd 100644 --- a/src/Sylius/Bundle/UiBundle/Tests/Functional/src/CustomContextProvider.php +++ b/src/Sylius/Bundle/UiBundle/Tests/Functional/src/CustomContextProvider.php @@ -14,16 +14,16 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Tests\Functional\src; use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface; -use Sylius\Bundle\UiBundle\Registry\TemplateBlock; +use Sylius\Bundle\UiBundle\Registry\Block; final class CustomContextProvider implements ContextProviderInterface { - public function provide(array $templateContext, TemplateBlock $templateBlock): array + public function provide(array $templateContext, Block $templateBlock): array { return $templateContext + ['custom' => 'yolo']; } - public function supports(TemplateBlock $templateBlock): bool + public function supports(Block $templateBlock): bool { return 'custom_context_provider' === $templateBlock->getEventName(); } diff --git a/src/Sylius/Bundle/UiBundle/Tests/Functional/src/SomeTwigComponent.php b/src/Sylius/Bundle/UiBundle/Tests/Functional/src/SomeTwigComponent.php new file mode 100644 index 0000000000..2ddc5fa7bb --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Tests/Functional/src/SomeTwigComponent.php @@ -0,0 +1,39 @@ +context) { + return 'no context'; + } + + $result = []; + + foreach ($this->context as $key => $value) { + $result[] = $key . '=' . $value; + } + + return implode(', ', $result); + } +} diff --git a/src/Sylius/Bundle/UiBundle/Tests/Functional/templates/blocks/twigComponent/someTwigComponent.html.twig b/src/Sylius/Bundle/UiBundle/Tests/Functional/templates/blocks/twigComponent/someTwigComponent.html.twig new file mode 100644 index 0000000000..e2e7985d81 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Tests/Functional/templates/blocks/twigComponent/someTwigComponent.html.twig @@ -0,0 +1,2 @@ +Hello from the Twig Component :) +Context: {{ contextAsString }} diff --git a/src/Sylius/Bundle/UiBundle/Tests/Functional/templates/templateEventsButComponent.txt.twig b/src/Sylius/Bundle/UiBundle/Tests/Functional/templates/templateEventsButComponent.txt.twig new file mode 100644 index 0000000000..bc0f916d20 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/Tests/Functional/templates/templateEventsButComponent.txt.twig @@ -0,0 +1,2 @@ +{{ sylius_template_event('template_event') }} +{{ sylius_template_event('template_event_with_context', { foo: 'bar' }) }} diff --git a/src/Sylius/Bundle/UiBundle/Twig/TemplateEventExtension.php b/src/Sylius/Bundle/UiBundle/Twig/TemplateEventExtension.php index 7f6a0411c9..fc0de5c0db 100644 --- a/src/Sylius/Bundle/UiBundle/Twig/TemplateEventExtension.php +++ b/src/Sylius/Bundle/UiBundle/Twig/TemplateEventExtension.php @@ -13,14 +13,14 @@ declare(strict_types=1); namespace Sylius\Bundle\UiBundle\Twig; -use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface; +use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; use Webmozart\Assert\Assert; final class TemplateEventExtension extends AbstractExtension { - public function __construct(private TemplateEventRendererInterface $templateEventRenderer) + public function __construct(private TwigEventRendererInterface $templateEventRenderer) { } @@ -28,6 +28,8 @@ final class TemplateEventExtension extends AbstractExtension { return [ new TwigFunction('sylius_template_event', [$this, 'render'], ['is_safe' => ['html']]), + new TwigFunction('twig_event', [$this, 'render'], ['is_safe' => ['html']]), + new TwigFunction('twig_event_name', [$this, 'createEventName']), ]; } @@ -41,6 +43,18 @@ final class TemplateEventExtension extends AbstractExtension } Assert::notEmpty($eventName); + /** @var non-empty-list $eventName */ + $eventName = array_filter($eventName, fn (?string $eventName) => $eventName !== null); + return $this->templateEventRenderer->render($eventName, $context); } + + public function createEventName(?string $eventName, string ...$suffixes): ?string + { + if ($eventName === null) { + return null; + } + + return implode('.', array_merge([$eventName], $suffixes)); + } } diff --git a/src/Sylius/Bundle/UiBundle/Twig/TestFormAttributeExtension.php b/src/Sylius/Bundle/UiBundle/Twig/TestFormAttributeExtension.php index dfd121c506..57e9900566 100644 --- a/src/Sylius/Bundle/UiBundle/Twig/TestFormAttributeExtension.php +++ b/src/Sylius/Bundle/UiBundle/Twig/TestFormAttributeExtension.php @@ -18,7 +18,7 @@ use Twig\TwigFunction; final class TestFormAttributeExtension extends AbstractExtension { - public function __construct(private string $environment) + public function __construct(private readonly string $environment, private readonly bool $isDebugEnabled) { } @@ -30,15 +30,38 @@ final class TestFormAttributeExtension extends AbstractExtension return [ new TwigFunction( 'sylius_test_form_attribute', - function (string $name, ?string $value = null): array { - if (str_starts_with($this->environment, 'test')) { - return ['attr' => ['data-test-' . $name => (string) $value]]; + [$this, 'getTestFormAttribute'], + ['is_safe' => ['html']], + ), + new TwigFunction( + 'sylius_test_form_attributes', + function (array $attributes): array { + if (!str_starts_with($this->environment, 'test') && $this->isDebugEnabled === false) { + return []; } - return []; + $result = []; + + foreach ($attributes as $name => $value) { + $result[sprintf('data-test-%s', $name)] = (string) $value; + } + + return ['attr' => $result]; }, ['is_safe' => ['html']], ), ]; } + + /** + * @return array{attr: non-empty-array}|array{} + */ + public function getTestFormAttribute(string $name, ?string $value = null): array + { + if (str_starts_with($this->environment, 'test') || $this->isDebugEnabled) { + return ['attr' => ['data-test-' . $name => (string) $value]]; + } + + return []; + } } diff --git a/src/Sylius/Bundle/UiBundle/Twig/TestHtmlAttributeExtension.php b/src/Sylius/Bundle/UiBundle/Twig/TestHtmlAttributeExtension.php index 9d5771c3b9..ad78a086cf 100644 --- a/src/Sylius/Bundle/UiBundle/Twig/TestHtmlAttributeExtension.php +++ b/src/Sylius/Bundle/UiBundle/Twig/TestHtmlAttributeExtension.php @@ -18,7 +18,7 @@ use Twig\TwigFunction; final class TestHtmlAttributeExtension extends AbstractExtension { - public function __construct(private string $env) + public function __construct(private readonly string $environment, private readonly bool $isDebugEnabled) { } @@ -31,7 +31,7 @@ final class TestHtmlAttributeExtension extends AbstractExtension new TwigFunction( 'sylius_test_html_attribute', function (string $name, ?string $value = null): string { - if (str_starts_with($this->env, 'test')) { + if (str_starts_with($this->environment, 'test') || $this->isDebugEnabled) { return sprintf('data-test-%s="%s"', $name, (string) $value); } diff --git a/src/Sylius/Bundle/UiBundle/composer.json b/src/Sylius/Bundle/UiBundle/composer.json index 87a163c488..9e41816209 100644 --- a/src/Sylius/Bundle/UiBundle/composer.json +++ b/src/Sylius/Bundle/UiBundle/composer.json @@ -36,15 +36,18 @@ "sylius-labs/polyfill-symfony-event-dispatcher": "^1.0.1", "sylius/grid-bundle": "^1.12", "symfony/config": "^6.4.0", + "symfony/expression-language": "^6.4.0", "symfony/framework-bundle": "^6.4.1", "symfony/security-core": "^6.4.0", "symfony/security-bundle": "^6.4.0", "symfony/templating": "^6.4.0", + "symfony/ux-live-component": "^2.17", + "symfony/ux-twig-component": "^2.17", "symfony/webpack-encore-bundle": "^1.17.1", "laminas/laminas-stdlib": "^3.3.1" }, "conflict": { - "twig/twig": "^1.0 || 3.9.0" + "twig/twig": "3.9.0" }, "require-dev": { "matthiasnoback/symfony-config-test": "^4.2", @@ -53,7 +56,7 @@ "phpunit/phpunit": "^9.5", "symfony/dependency-injection": "^6.4.1", "symfony/form": "^6.4.1", - "twig/twig": "^2.12 || ^3.3" + "twig/twig": "~3.8.0" }, "config": { "allow-plugins": { diff --git a/src/Sylius/Bundle/UiBundle/spec/ContextProvider/CompositeContextProviderSpec.php b/src/Sylius/Bundle/UiBundle/spec/ContextProvider/CompositeContextProviderSpec.php new file mode 100644 index 0000000000..9838a8aa00 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/spec/ContextProvider/CompositeContextProviderSpec.php @@ -0,0 +1,77 @@ +beConstructedWith([]); + + $this->shouldImplement(ContextProviderInterface::class); + } + + function it_throws_an_exception_when_any_of_passed_context_providers_is_not_a_context_provider(): void + { + $this->beConstructedWith([new \stdClass()]); + + $this->shouldThrow(InvalidArgumentException::class)->duringInstantiation(); + } + + function it_throws_an_exception_when_no_context_provider_supports_a_given_block( + ContextProviderInterface $someContextProvider, + Block $someBlock, + ): void { + $someBlock->getName()->willReturn('some_block'); + + $someContextProvider->supports($someBlock)->willReturn(false); + + $this->beConstructedWith([$someContextProvider]); + + $this->shouldThrow(new NoSupportedContextProvider('No supported context provider found for block "some_block".'))->during('provide', [[], $someBlock]); + } + + function it_returns_always_true_for_supports(Block $someBlock): void + { + $this->beConstructedWith([]); + + $this->supports($someBlock)->shouldReturn(true); + } + + function it_returns_a_context_for_a_first_supported_context_provider( + ContextProviderInterface $someContextProvider, + ContextProviderInterface $anotherContextProvider, + ContextProviderInterface $yetAnotherContextProvider, + Block $someBlock, + ): void { + $someBlock->getName()->willReturn('some_block'); + + $someContextProvider->supports($someBlock)->willReturn(false); + + $anotherContextProvider->supports($someBlock)->willReturn(true); + $anotherContextProvider->provide(['foo' => 'bar'], $someBlock)->willReturn(['foo' => 'qux']); + + $yetAnotherContextProvider->supports($someBlock)->shouldNotBeCalled(); + + $this->beConstructedWith([$someContextProvider, $anotherContextProvider]); + + $this->provide(['foo' => 'bar'], $someBlock)->shouldReturn(['foo' => 'qux']); + } +} diff --git a/src/Sylius/Bundle/UiBundle/spec/ContextProvider/DefaultContextProviderSpec.php b/src/Sylius/Bundle/UiBundle/spec/ContextProvider/DefaultContextProviderSpec.php index ced9468556..b2fbdca261 100644 --- a/src/Sylius/Bundle/UiBundle/spec/ContextProvider/DefaultContextProviderSpec.php +++ b/src/Sylius/Bundle/UiBundle/spec/ContextProvider/DefaultContextProviderSpec.php @@ -26,7 +26,7 @@ final class DefaultContextProviderSpec extends ObjectBehavior function it_replaces_block_context_with_a_template_context(): void { - $templateBlock = new TemplateBlock('block_name', 'event_name', 'block.txt.twig', ['foo' => 'quux', 'quuz' => 'corge'], 0, true); + $templateBlock = new TemplateBlock('block_name', 'event_name', 'block.txt.twig', ['foo' => 'quux', 'quuz' => 'corge'], 0, true, null); $this ->provide(['foo' => 'bar', 'baz' => 'qux'], $templateBlock) @@ -41,12 +41,12 @@ final class DefaultContextProviderSpec extends ObjectBehavior function it_supports_all_template_blocks(): void { $this - ->supports(new TemplateBlock('block_name', 'event_name', null, null, null, null)) + ->supports(new TemplateBlock('block_name', 'event_name', null, null, null, null, null)) ->shouldReturn(true) ; $this - ->supports(new TemplateBlock('block_name', 'event_name', 'block.txt.twig', ['foo' => 'quux', 'quuz' => 'corge'], 0, true)) + ->supports(new TemplateBlock('block_name', 'event_name', 'block.txt.twig', ['foo' => 'quux', 'quuz' => 'corge'], 0, true, null)) ->shouldReturn(true) ; } diff --git a/src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockRegistrySpec.php b/src/Sylius/Bundle/UiBundle/spec/Registry/BlockRegistrySpec.php similarity index 66% rename from src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockRegistrySpec.php rename to src/Sylius/Bundle/UiBundle/spec/Registry/BlockRegistrySpec.php index a4c1a74798..4ad2c51163 100644 --- a/src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockRegistrySpec.php +++ b/src/Sylius/Bundle/UiBundle/spec/Registry/BlockRegistrySpec.php @@ -14,95 +14,98 @@ declare(strict_types=1); namespace spec\Sylius\Bundle\UiBundle\Registry; use PhpSpec\ObjectBehavior; +use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface; +use Sylius\Bundle\UiBundle\Registry\ComponentBlock; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; -use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface; -final class TemplateBlockRegistrySpec extends ObjectBehavior +final class BlockRegistrySpec extends ObjectBehavior { function let(): void { $this->beConstructedWith([]); } - function it_is_a_template_block_registry(): void + function it_is_a_block_registry(): void { - $this->shouldImplement(TemplateBlockRegistryInterface::class); + $this->shouldImplement(BlockRegistryInterface::class); } function it_returns_all_template_blocks(): void { - $templateBlock = new TemplateBlock('block_name', 'event', 'block.html.twig', [], 10, true); + $templateBlock = new TemplateBlock('block_name', 'event', 'block.html.twig', [], 10, true, null); $this->beConstructedWith(['event' => ['block_name' => $templateBlock]]); $this->all()->shouldReturn(['event' => ['block_name' => $templateBlock]]); } - function it_returns_enabled_template_blocks_for_a_given_event(): void + function it_returns_enabled_blocks_for_a_given_event(): void { - $firstTemplateBlock = new TemplateBlock('first_block', 'event', 'first.html.twig', [], 0, true); - $secondTemplateBlock = new TemplateBlock('second_block', 'event', 'second.html.twig', [], 10, false); - $thirdTemplateBlock = new TemplateBlock('third_block', 'event', 'third.html.twig', [], 50, true); + $firstBlock = new TemplateBlock('first_block', 'event', 'first.html.twig', [], 0, true, null); + $secondBlock = new TemplateBlock('second_block', 'event', 'second.html.twig', [], 10, false, null); + $thirdBlock = new TemplateBlock('third_block', 'event', 'third.html.twig', [], 50, true, null); + $fourthBlock = new ComponentBlock('fourth_block', 'event', 'fourth.html.twig', [], [], 0, null); $this->beConstructedWith([ 'event' => [ - 'first_block' => $firstTemplateBlock, - 'second_block' => $secondTemplateBlock, + 'first_block' => $firstBlock, + 'second_block' => $secondBlock, ], 'another_event' => [ - 'third_block' => $thirdTemplateBlock, + 'third_block' => $thirdBlock, + 'fourth_block' => $fourthBlock, ], ]); - $this->findEnabledForEvents(['event'])->shouldReturn([$firstTemplateBlock]); + $this->findEnabledForEvents(['event'])->shouldReturn([$firstBlock]); } - function it_returns_enabled_template_blocks_for_multiple_events(): void + function it_returns_enabled_blocks_for_multiple_events(): void { $this->beConstructedWith([ 'generic_event' => ['block' => new TemplateBlock('block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, true)], - 'specific_event_template' => ['block' => new TemplateBlock('block', 'specific_event_template', 'specific.html.twig', null, null, null)], - 'specific_event_context' => ['block' => new TemplateBlock('block', 'specific_event_context', null, ['other' => 'context'], null, null)], - 'specific_event_priority' => ['block' => new TemplateBlock('block', 'specific_event_priority', null, null, 10, null)], - 'specific_event_enabled' => ['block' => new TemplateBlock('block', 'specific_event_enabled', null, null, null, false)], + 'specific_event_template' => ['block' => new TemplateBlock('block', 'specific_event_template', 'specific.html.twig', null, null, null, null)], + 'specific_event_context' => ['block' => new TemplateBlock('block', 'specific_event_context', null, ['other' => 'context'], null, null, null)], + 'specific_event_priority' => ['block' => new TemplateBlock('block', 'specific_event_priority', null, null, 10, null, null)], + 'specific_event_enabled' => ['block' => new TemplateBlock('block', 'specific_event_enabled', null, null, null, false, null)], ]); $this->findEnabledForEvents(['specific_event_template', 'generic_event'])->shouldIterateLike([ - new TemplateBlock('block', 'specific_event_template', 'specific.html.twig', ['foo' => 'bar'], 0, true), + new TemplateBlock('block', 'specific_event_template', 'specific.html.twig', ['foo' => 'bar'], 0, true, null), ]); $this->findEnabledForEvents(['specific_event_context', 'generic_event'])->shouldIterateLike([ - new TemplateBlock('block', 'specific_event_context', 'generic.html.twig', ['other' => 'context'], 0, true), + new TemplateBlock('block', 'specific_event_context', 'generic.html.twig', ['other' => 'context'], 0, true, null), ]); $this->findEnabledForEvents(['specific_event_priority', 'generic_event'])->shouldIterateLike([ - new TemplateBlock('block', 'specific_event_priority', 'generic.html.twig', ['foo' => 'bar'], 10, true), + new TemplateBlock('block', 'specific_event_priority', 'generic.html.twig', ['foo' => 'bar'], 10, true, null), ]); $this->findEnabledForEvents(['specific_event_enabled', 'generic_event'])->shouldReturn([]); $this->findEnabledForEvents(['specific_event_priority', 'specific_event_template', 'generic_event'])->shouldIterateLike([ - new TemplateBlock('block', 'specific_event_priority', 'specific.html.twig', ['foo' => 'bar'], 10, true), + new TemplateBlock('block', 'specific_event_priority', 'specific.html.twig', ['foo' => 'bar'], 10, true, null), ]); } - function it_returns_enabled_template_blocks_sorted_by_priority_for_multiple_events(): void + function it_returns_enabled_blocks_sorted_by_priority_for_multiple_events(): void { $this->beConstructedWith([ 'generic_event' => [ - 'first_block' => new TemplateBlock('first_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 50, true), - 'third_block' => new TemplateBlock('third_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], -10, true), - 'second_block' => new TemplateBlock('second_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, true), - 'invisible_block' => new TemplateBlock('invisible_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, false), + 'first_block' => new TemplateBlock('first_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 50, true, null), + 'third_block' => new TemplateBlock('third_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], -10, true, null), + 'second_block' => new TemplateBlock('second_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, true, null), + 'invisible_block' => new TemplateBlock('invisible_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, false, null), ], 'specific_event' => [ - 'additional_block' => new TemplateBlock('additional_block', 'specific_event', 'specific.html.twig', [], 75, true), - 'second_block' => new TemplateBlock('second_block', 'specific_event', null, null, null, false), - 'third_block' => new TemplateBlock('third_block', 'specific_event', null, null, 100, null), - 'invisible_block' => new TemplateBlock('invisible_block', 'specific_event', null, [], null, null), + 'additional_block' => new TemplateBlock('additional_block', 'specific_event', 'specific.html.twig', [], 75, true, null), + 'second_block' => new TemplateBlock('second_block', 'specific_event', null, null, null, false, null), + 'third_block' => new TemplateBlock('third_block', 'specific_event', null, null, 100, null, null), + 'invisible_block' => new TemplateBlock('invisible_block', 'specific_event', null, [], null, null, null), ], ]); $this->findEnabledForEvents(['specific_event', 'generic_event'])->shouldIterateLike([ - new TemplateBlock('third_block', 'specific_event', 'generic.html.twig', ['foo' => 'bar'], 100, true), - new TemplateBlock('additional_block', 'specific_event', 'specific.html.twig', [], 75, true), - new TemplateBlock('first_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 50, true), + new TemplateBlock('third_block', 'specific_event', 'generic.html.twig', ['foo' => 'bar'], 100, true, null), + new TemplateBlock('additional_block', 'specific_event', 'specific.html.twig', [], 75, true, null), + new TemplateBlock('first_block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 50, true, null), ]); } } diff --git a/src/Sylius/Bundle/UiBundle/spec/Registry/ComponentBlockSpec.php b/src/Sylius/Bundle/UiBundle/spec/Registry/ComponentBlockSpec.php new file mode 100644 index 0000000000..d80597d49a --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/spec/Registry/ComponentBlockSpec.php @@ -0,0 +1,100 @@ +beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false); + + $this->getName()->shouldReturn('block_name'); + $this->getEventName()->shouldReturn('event_name'); + $this->getComponentName()->shouldReturn('MyComponent'); + $this->getComponentInputs()->shouldReturn(['my' => 'input']); + $this->getContext()->shouldReturn(['my' => 'context']); + $this->getPriority()->shouldReturn(10); + $this->isEnabled()->shouldReturn(false); + } + + function it_overwrites_a_component_block_with_an_another_component_block(): void + { + $this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false); + + $this + ->overwriteWith( + new ComponentBlock( + 'block_name', + 'specific_event_name', + 'MyAnotherComponent', + ['my' => 'another_input'], + ['my' => 'another_context'], + 20, + true, + ), + ) + ->shouldBeLike( + new ComponentBlock( + 'block_name', + 'specific_event_name', + 'MyAnotherComponent', + ['my' => 'another_input'], + ['my' => 'another_context'], + 20, + true, + ), + ) + ; + } + + function it_throws_an_exception_if_trying_to_overwrite_with_a_differently_named_block(): void + { + $this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false); + + $this->shouldThrow(\DomainException::class)->during( + 'overwriteWith', + [ + new ComponentBlock( + 'another_block_name', + 'specific_event_name', + 'MyComponent', + [], + [], + 0, + false, + ), + ], + ); + } + + function it_throws_an_exception_when_trying_to_override_template_block_with_template_block(): void + { + $this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false); + + $exceptionMessage = sprintf( + 'Trying to overwrite component block "%s" with block of different type "%s".', + 'block_name', + 'Sylius\Bundle\UiBundle\Registry\TemplateBlock', + ); + + $this + ->shouldThrow(new \DomainException($exceptionMessage)) + ->during('overwriteWith', [new TemplateBlock('block_name', 'specific_event_name', null, null, null, true)]) + ; + } +} diff --git a/src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockSpec.php b/src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockSpec.php index bf74737465..6d31169e2b 100644 --- a/src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockSpec.php +++ b/src/Sylius/Bundle/UiBundle/spec/Registry/TemplateBlockSpec.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace spec\Sylius\Bundle\UiBundle\Registry; use PhpSpec\ObjectBehavior; +use Sylius\Bundle\UiBundle\Registry\ComponentBlock; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; final class TemplateBlockSpec extends ObjectBehavior @@ -71,4 +72,20 @@ final class TemplateBlockSpec extends ObjectBehavior $this->getPriority()->shouldReturn(0); $this->isEnabled()->shouldReturn(true); } + + function it_throws_an_exception_when_trying_to_override_template_block_with_component_block(): void + { + $this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false); + + $exceptionMessage = sprintf( + 'Trying to overwrite template block "%s" with block of different type "%s".', + 'block_name', + 'Sylius\Bundle\UiBundle\Registry\ComponentBlock', + ); + + $this + ->shouldThrow(new \DomainException($exceptionMessage)) + ->during('overwriteWith', [new ComponentBlock('block_name', 'specific_event_name', 'MyComponent', [], [], 0, false)]) + ; + } } diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/CompositeBlockRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/CompositeBlockRendererSpec.php new file mode 100644 index 0000000000..4f2f65282c --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/spec/Renderer/CompositeBlockRendererSpec.php @@ -0,0 +1,74 @@ +beConstructedWith([]); + + $this->shouldImplement(BlockRendererInterface::class); + } + + function it_throws_an_exception_when_any_of_passed_block_renderers_is_not_a_block_renderer(): void + { + $this->beConstructedWith([new \stdClass()]); + + $this->shouldThrow(InvalidArgumentException::class)->duringInstantiation(); + } + + function it_throws_an_exception_when_no_block_renderers_supports_a_given_block( + SupportableBlockRendererInterface $someBlockRenderer, + Block $someBlock, + ): void { + $someBlock->getName()->willReturn('some_block'); + + $someBlockRenderer->supports($someBlock)->willReturn(false); + + $this->beConstructedWith([$someBlockRenderer]); + + $this + ->shouldThrow(new NoSupportedBlockRenderer('No supported block renderer found for "some_block" block.')) + ->during('render', [$someBlock, []]) + ; + } + + function it_renders_a_block_using_a_first_supported_block_renderer( + SupportableBlockRendererInterface $someBlockRenderer, + SupportableBlockRendererInterface $anotherBlockRenderer, + SupportableBlockRendererInterface $yetAnotherBlockRenderer, + Block $someBlock, + ): void { + $someBlock->getName()->willReturn('some_block'); + + $someBlockRenderer->supports($someBlock)->willReturn(false); + + $anotherBlockRenderer->supports($someBlock)->willReturn(true); + $anotherBlockRenderer->render($someBlock, [])->willReturn('Rendered block'); + + $yetAnotherBlockRenderer->supports($someBlock)->shouldNotBeCalled(); + + $this->beConstructedWith([$someBlockRenderer, $anotherBlockRenderer, $yetAnotherBlockRenderer]); + + $this->render($someBlock, [])->shouldReturn('Rendered block'); + } +} diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/DelegatingTemplateEventRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/DelegatingTwigEventRendererSpec.php similarity index 60% rename from src/Sylius/Bundle/UiBundle/spec/Renderer/DelegatingTemplateEventRendererSpec.php rename to src/Sylius/Bundle/UiBundle/spec/Renderer/DelegatingTwigEventRendererSpec.php index 7e059be237..3f11dd4fdc 100644 --- a/src/Sylius/Bundle/UiBundle/spec/Renderer/DelegatingTemplateEventRendererSpec.php +++ b/src/Sylius/Bundle/UiBundle/spec/Renderer/DelegatingTwigEventRendererSpec.php @@ -15,29 +15,29 @@ namespace spec\Sylius\Bundle\UiBundle\Renderer; use PhpSpec\ObjectBehavior; use Prophecy\Argument; +use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; -use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface; -use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface; -use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface; +use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface; +use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface; -final class DelegatingTemplateEventRendererSpec extends ObjectBehavior +final class DelegatingTwigEventRendererSpec extends ObjectBehavior { - function let(TemplateBlockRegistryInterface $templateBlockRegistry, TemplateBlockRendererInterface $templateBlockRenderer): void + function let(BlockRegistryInterface $templateBlockRegistry, BlockRendererInterface $templateBlockRenderer): void { $this->beConstructedWith($templateBlockRegistry, $templateBlockRenderer); } - function it_is_a_template_event_renderer(): void + function it_is_a_twig_event_renderer(): void { - $this->shouldImplement(TemplateEventRendererInterface::class); + $this->shouldImplement(TwigEventRendererInterface::class); } - function it_renders_template_events( - TemplateBlockRegistryInterface $templateBlockRegistry, - TemplateBlockRendererInterface $templateBlockRenderer, + function it_renders_blocks_for_a_given_template( + BlockRegistryInterface $templateBlockRegistry, + BlockRendererInterface $templateBlockRenderer, ): void { - $firstTemplateBlock = new TemplateBlock('first_block', 'best_event_ever', 'firstBlock.txt.twig', [], 0, true); - $secondTemplateBlock = new TemplateBlock('second_block', 'best_event_ever', 'secondBlock.txt.twig', [], 0, true); + $firstTemplateBlock = new TemplateBlock('first_block', 'best_event_ever', 'firstBlock.txt.twig', [], 0, true, null); + $secondTemplateBlock = new TemplateBlock('second_block', 'best_event_ever', 'secondBlock.txt.twig', [], 0, true, null); $templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([$firstTemplateBlock, $secondTemplateBlock]); @@ -48,8 +48,8 @@ final class DelegatingTemplateEventRendererSpec extends ObjectBehavior } function it_returns_an_empty_string_if_no_blocks_are_found_for_an_event( - TemplateBlockRegistryInterface $templateBlockRegistry, - TemplateBlockRendererInterface $templateBlockRenderer, + BlockRegistryInterface $templateBlockRegistry, + BlockRendererInterface $templateBlockRenderer, ): void { $templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([]); diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugBlockRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugBlockRendererSpec.php new file mode 100644 index 0000000000..c8ddb40413 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugBlockRendererSpec.php @@ -0,0 +1,70 @@ +beConstructedWith($templateBlockRenderer); + } + + function it_is_a_block_renderer(): void + { + $this->shouldImplement(BlockRendererInterface::class); + } + + function it_does_not_render_html_debug_comment_if_template_block_is_not_an_html_twig_file_path( + BlockRendererInterface $templateBlockRenderer, + ): void { + $templateBlock = new TemplateBlock('block_name', 'event_name', 'template', [], 0, true); + + $templateBlockRenderer->render($templateBlock, [])->willReturn('template'); + + $this->render($templateBlock)->shouldReturn('template'); + } + + function it_renders_html_debug_comment_if_template_block_is_an_html_twig_file_path( + BlockRendererInterface $templateBlockRenderer, + ): void { + $templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], 0, true); + + $templateBlockRenderer->render($templateBlock, [])->willReturn('template'); + + $this->render($templateBlock)->shouldReturn( + '' . "\n" . + 'template' . "\n" . + '', + ); + } + + function it_renders_html_debug_comment_if_the_block_is_a_component( + BlockRendererInterface $templateBlockRenderer, + ): void { + $componentBlock = new ComponentBlock('block_name', 'event_name', 'Component', [], [], 0, true); + + $templateBlockRenderer->render($componentBlock, ['some' => 'context'])->willReturn('template'); + + $this->render($componentBlock, ['some' => 'context'])->shouldReturn( + '' . "\n" . + 'template' . "\n" . + '', + ); + } +} diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTemplateBlockRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTemplateBlockRendererSpec.php deleted file mode 100644 index a40f4a13f6..0000000000 --- a/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTemplateBlockRendererSpec.php +++ /dev/null @@ -1,58 +0,0 @@ -beConstructedWith($templateBlockRenderer); - } - - function it_is_a_template_block_renderer(): void - { - $this->shouldImplement(TemplateBlockRendererInterface::class); - } - - function it_renders_html_debug_comment_prepending_the_block_if_rendering_html_template( - TemplateBlockRendererInterface $templateBlockRenderer, - ): void { - $templateBlockRenderer->render(Argument::cetera())->willReturn('Block content'); - - $this->render( - new TemplateBlock('block_name', 'event_name', 'block.html.twig', [], 0, true), - ['foo' => 'bar'], - )->shouldReturn( - '' . "\n" . - 'Block content' . "\n" . - '', - ); - } - - function it_does_not_render_html_debug_comment_prepending_the_block_if_rendering_non_html_template( - TemplateBlockRendererInterface $templateBlockRenderer, - ): void { - $templateBlockRenderer->render(Argument::cetera())->willReturn('Block content'); - - $this->render( - new TemplateBlock('block_name', 'event_name', 'block.txt.twig', [], 0, true), - ['foo' => 'bar'], - )->shouldReturn('Block content'); - } -} diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTemplateEventRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTemplateEventRendererSpec.php deleted file mode 100644 index 020f5b3f5d..0000000000 --- a/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTemplateEventRendererSpec.php +++ /dev/null @@ -1,81 +0,0 @@ -beConstructedWith($templateEventRenderer, $templateBlockRegistry); - } - - function it_is_a_template_event_renderer(): void - { - $this->shouldImplement(TemplateEventRendererInterface::class); - } - - function it_renders_html_debug_comment_if_at_least_one_template_is_a_html_one( - TemplateEventRendererInterface $templateEventRenderer, - TemplateBlockRegistryInterface $templateBlockRegistry, - ): void { - $firstTemplateBlock = new TemplateBlock('first_block', 'event_block', 'firstBlock.txt.twig', [], 0, true); - $secondTemplateBlock = new TemplateBlock('second_block', 'event_block', 'secondBlock.html.twig', [], 0, true); - - $templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([$firstTemplateBlock, $secondTemplateBlock]); - - $templateEventRenderer->render(['best_event_ever'], ['foo' => 'bar'])->willReturn("First block\nSecond block"); - - $this->render(['best_event_ever'], ['foo' => 'bar'])->shouldReturn( - '' . "\n" . - 'First block' . "\n" . - 'Second block' . "\n" . - '', - ); - } - - function it_does_not_render_html_debug_comment_if_no_html_templates_are_found( - TemplateEventRendererInterface $templateEventRenderer, - TemplateBlockRegistryInterface $templateBlockRegistry, - ): void { - $firstTemplateBlock = new TemplateBlock('first_block', 'event_block', 'firstBlock.txt.twig', [], 0, true); - $secondTemplateBlock = new TemplateBlock('second_block', 'event_block', 'secondBlock.txt.twig', [], 0, true); - - $templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([$firstTemplateBlock, $secondTemplateBlock]); - - $templateEventRenderer->render(['best_event_ever'], ['foo' => 'bar'])->willReturn("First block\nSecond block"); - - $this->render(['best_event_ever'], ['foo' => 'bar'])->shouldReturn("First block\nSecond block"); - } - - function it_returns_html_debug_comment_if_no_blocks_are_found_for_an_event( - TemplateEventRendererInterface $templateEventRenderer, - TemplateBlockRegistryInterface $templateBlockRegistry, - ): void { - $templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([]); - - $templateEventRenderer->render(Argument::cetera())->willReturn(''); - - $this->render(['best_event_ever'])->shouldReturn( - '' . "\n" . - "\n" . - '', - ); - } -} diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTwigEventRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTwigEventRendererSpec.php new file mode 100644 index 0000000000..b3af03804d --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/spec/Renderer/HtmlDebugTwigEventRendererSpec.php @@ -0,0 +1,95 @@ +beConstructedWith($templateEventRenderer, $templateBlockRegistry); + } + + function it_is_a_template_event_renderer(): void + { + $this->shouldImplement(TwigEventRendererInterface::class); + } + + function it_does_not_render_html_debug_comments_when_there_are_no_template_blocks_with_a_defined_component_nor_template( + TwigEventRendererInterface $templateEventRenderer, + BlockRegistryInterface $templateBlockRegistry, + ): void { + $templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([ + new TemplateBlock('some_block_one', 'some_event', 'some content', null, null, true, null), + ]); + + $templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content'); + + $this->render(['event_name'])->shouldReturn('rendered_content'); + } + + function it_renders_html_debug_comment_when_no_template_block_passed( + TwigEventRendererInterface $templateEventRenderer, + BlockRegistryInterface $templateBlockRegistry, + ): void { + $templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([]); + + $templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content'); + + $this->render(['event_name'])->shouldReturn( + '' . "\n" . + 'rendered_content' . "\n" . + '', + ); + } + + function it_renders_html_debug_comment_when_at_least_one_block_has_a_configured_component( + TwigEventRendererInterface $templateEventRenderer, + BlockRegistryInterface $templateBlockRegistry, + ): void { + $templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([ + new ComponentBlock('some_block_one', 'some_event', 'Component', [], [], 0, true), + ]); + + $templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content'); + + $this->render(['event_name'])->shouldReturn( + '' . "\n" . + 'rendered_content' . "\n" . + '', + ); + } + + function it_renders_html_debug_comment_when_at_least_one_block_has_a_configured_twig_template( + TwigEventRendererInterface $templateEventRenderer, + BlockRegistryInterface $templateBlockRegistry, + ): void { + $templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([ + new TemplateBlock('some_block_one', 'some_event', 'template.html.twig', null, null, true), + ]); + + $templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content'); + + $this->render(['event_name'])->shouldReturn( + '' . "\n" . + 'rendered_content' . "\n" . + '', + ); + } +} diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigComponentBlockRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigComponentBlockRendererSpec.php new file mode 100644 index 0000000000..602f3eb1b8 --- /dev/null +++ b/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigComponentBlockRendererSpec.php @@ -0,0 +1,104 @@ +beConstructedWith( + $componentRenderer, + $contextProvider, + $expressionLanguage, + ); + } + + function it_returns_true_if_block_is_supported(): void + { + $templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], 0, true); + $componentBlock = new ComponentBlock('block_name', 'event_name', 'Component', [], [], 0, true); + + $this->supports($templateBlock)->shouldReturn(false); + $this->supports($componentBlock)->shouldReturn(true); + } + + function it_throws_an_exception_when_trying_to_render_unsupported_block(): void + { + $templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], 0, true); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('render', [$templateBlock]) + ; + } + + function it_renders_component_block( + ComponentRendererInterface $componentRenderer, + ContextProviderInterface $contextProvider, + ExpressionLanguage $expressionLanguage, + ): void { + $componentBlock = new ComponentBlock( + 'block_name', + 'event_name', + 'Component', + [ + 'foo' => 'bar', + 'bar' => 'expr:baz', + 'nested' => [ + 'foo' => 'expr:bar', + 'bar' => 'expr:baz', + ], + ], + [], + 0, + true, + ); + + $context = [ + 'foo' => 'bar', + 'bar' => 'baz', + 'baz' => 'qux', + ]; + + $contextProvider->provide([], $componentBlock)->willReturn($context); + + $expressionLanguage->evaluate('foo', ['context' => $context])->willReturn('bar'); + $expressionLanguage->evaluate('bar', ['context' => $context])->willReturn('baz'); + $expressionLanguage->evaluate('baz', ['context' => $context])->willReturn('qux'); + + $componentRenderer + ->createAndRender('Component', [ + 'foo' => 'bar', + 'bar' => 'qux', + 'nested' => [ + 'foo' => 'baz', + 'bar' => 'qux', + ], + ]) + ->willReturn('rendered_component') + ; + + $this->render($componentBlock)->shouldReturn('rendered_component'); + } +} diff --git a/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigTemplateBlockRendererSpec.php b/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigTemplateBlockRendererSpec.php index e377111abd..76354358b8 100644 --- a/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigTemplateBlockRendererSpec.php +++ b/src/Sylius/Bundle/UiBundle/spec/Renderer/TwigTemplateBlockRendererSpec.php @@ -16,8 +16,9 @@ namespace spec\Sylius\Bundle\UiBundle\Renderer; use PhpSpec\ObjectBehavior; use Prophecy\Argument; use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface; +use Sylius\Bundle\UiBundle\Registry\ComponentBlock; use Sylius\Bundle\UiBundle\Registry\TemplateBlock; -use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface; +use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface; use Twig\Environment; final class TwigTemplateBlockRendererSpec extends ObjectBehavior @@ -35,7 +36,17 @@ final class TwigTemplateBlockRendererSpec extends ObjectBehavior function it_is_a_template_block_renderer(): void { - $this->shouldImplement(TemplateBlockRendererInterface::class); + $this->shouldImplement(BlockRendererInterface::class); + } + + function it_throws_an_exception_when_trying_to_render_unsupported_block(): void + { + $templateBlock = new ComponentBlock('block_name', 'event_name', 'Component', [], [], 0, true); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('render', [$templateBlock]) + ; } function it_renders_a_template_block( @@ -43,7 +54,7 @@ final class TwigTemplateBlockRendererSpec extends ObjectBehavior ContextProviderInterface $firstContextProvider, ContextProviderInterface $secondContextProvider, ): void { - $templateBlock = new TemplateBlock('block_name', 'event_name', 'block.txt.twig', ['sample' => 'Hi', 'switch' => true], 0, true); + $templateBlock = new TemplateBlock('block_name', 'event_name', 'block.txt.twig', ['sample' => 'Hi', 'switch' => true], 0, true, null); $twig->render('block.txt.twig', ['sample' => 'Hello', 'switch' => true])->willReturn('Block content'); diff --git a/src/Sylius/Bundle/UserBundle/composer.json b/src/Sylius/Bundle/UserBundle/composer.json index 3c4be7c091..7aef1527da 100644 --- a/src/Sylius/Bundle/UserBundle/composer.json +++ b/src/Sylius/Bundle/UserBundle/composer.json @@ -50,8 +50,7 @@ "webmozart/assert": "^1.9" }, "conflict": { - "doctrine/orm": "2.15.2", - "twig/twig": "^3.0" + "doctrine/orm": "2.15.2" }, "require-dev": { "hwi/oauth-bundle": "^1.1 || ^2.0@beta", diff --git a/src/Sylius/Component/Core/Factory/PromotionRuleFactoryInterface.php b/src/Sylius/Component/Core/Factory/PromotionRuleFactoryInterface.php index e06844ba48..5bbfedd581 100644 --- a/src/Sylius/Component/Core/Factory/PromotionRuleFactoryInterface.php +++ b/src/Sylius/Component/Core/Factory/PromotionRuleFactoryInterface.php @@ -29,8 +29,6 @@ interface PromotionRuleFactoryInterface extends FactoryInterface public function createHasTaxon(array $taxons): PromotionRuleInterface; - public function createItemsFromTaxonTotal(string $channelCode, string $taxonCode, int $amount): PromotionRuleInterface; - public function createNthOrder(int $nth): PromotionRuleInterface; public function createContainsProduct(string $productCode): PromotionRuleInterface; diff --git a/src/Sylius/Component/Core/Promotion/Checker/Rule/ItemTotalRuleChecker.php b/src/Sylius/Component/Core/Promotion/Checker/Rule/ItemTotalRuleChecker.php index 325479771c..0b7599fd05 100644 --- a/src/Sylius/Component/Core/Promotion/Checker/Rule/ItemTotalRuleChecker.php +++ b/src/Sylius/Component/Core/Promotion/Checker/Rule/ItemTotalRuleChecker.php @@ -20,6 +20,8 @@ use Sylius\Component\Promotion\Model\PromotionSubjectInterface; final class ItemTotalRuleChecker implements RuleCheckerInterface { + public const TYPE = 'item_total'; + public function __construct(private ?RuleCheckerInterface $itemTotalRuleChecker = null) { if ($this->itemTotalRuleChecker instanceof self) { diff --git a/src/Sylius/Component/Order/Repository/OrderRepositoryInterface.php b/src/Sylius/Component/Order/Repository/OrderRepositoryInterface.php index 7e4b59773b..79e000057d 100644 --- a/src/Sylius/Component/Order/Repository/OrderRepositoryInterface.php +++ b/src/Sylius/Component/Order/Repository/OrderRepositoryInterface.php @@ -27,7 +27,7 @@ interface OrderRepositoryInterface extends RepositoryInterface public function countPlacedOrders(): int; /** - * @return array|OrderInterface[] + * @return array|T[] */ public function findLatest(int $count): array; diff --git a/src/Sylius/Component/Product/Repository/ProductOptionRepositoryInterface.php b/src/Sylius/Component/Product/Repository/ProductOptionRepositoryInterface.php index b8d1bc6a7a..113b72a3ff 100644 --- a/src/Sylius/Component/Product/Repository/ProductOptionRepositoryInterface.php +++ b/src/Sylius/Component/Product/Repository/ProductOptionRepositoryInterface.php @@ -32,9 +32,11 @@ interface ProductOptionRepositoryInterface extends RepositoryInterface public function findByName(string $name, string $locale): array; /** + * @param array|null $excludes + * * @return ProductOptionInterface[] */ - public function findByPhrase(string $phrase, string $locale, int $limit = 10): array; + public function findByPhrase(string $phrase, string $locale, int $limit = 10, ?array $excludes = null): array; /** * @param string[] $codes diff --git a/src/Sylius/Component/Taxonomy/Repository/TaxonRepositoryInterface.php b/src/Sylius/Component/Taxonomy/Repository/TaxonRepositoryInterface.php index d7962bfae2..0ef37cc8cb 100644 --- a/src/Sylius/Component/Taxonomy/Repository/TaxonRepositoryInterface.php +++ b/src/Sylius/Component/Taxonomy/Repository/TaxonRepositoryInterface.php @@ -46,9 +46,11 @@ interface TaxonRepositoryInterface extends RepositoryInterface public function findByName(string $name, string $locale): array; /** + * @param array|null $excludes + * * @return array|TaxonInterface[] */ - public function findByNamePart(string $phrase, ?string $locale = null, ?int $limit = null): array; + public function findByNamePart(string $phrase, ?string $locale = null, ?int $limit = null, ?array $excludes = null): array; public function createListQueryBuilder(): QueryBuilder; } diff --git a/symfony.lock b/symfony.lock index 0d3692c377..36d0121891 100644 --- a/symfony.lock +++ b/symfony.lock @@ -1,11 +1,17 @@ { + "aeon-php/calendar": { + "version": "0.15.0" + }, + "alcohol/iso4217": { + "version": "4.0.0" + }, "api-platform/core": { - "version": "2.7", + "version": "2.5", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", + "branch": "master", "version": "2.5", - "ref": "b86557ce5677fa855b1b2608f4a4bc4a8fed8be7" + "ref": "a93061567140e386f107be75340ac2aee3f86cbf" }, "files": [ "config/packages/api_platform.yaml", @@ -14,85 +20,242 @@ ] }, "babdev/pagerfanta-bundle": { - "version": "v3.8.0" + "version": "v2.8.0" + }, + "behat/behat": { + "version": "v3.7.0" + }, + "behat/gherkin": { + "version": "v4.6.2" + }, + "behat/mink-selenium2-driver": { + "version": "v1.4.0" + }, + "behat/transliterator": { + "version": "v1.3.0" + }, + "clue/stream-filter": { + "version": "v1.4.1" + }, + "coduo/php-matcher": { + "version": "4.0.0" + }, + "coduo/php-to-string": { + "version": "3.0.0" + }, + "composer/semver": { + "version": "1.5.1" + }, + "dealerdirect/phpcodesniffer-composer-installer": { + "version": "v0.7.0" + }, + "dmore/behat-chrome-extension": { + "version": "1.3.0" + }, + "dmore/chrome-mink-driver": { + "version": "2.7.0" }, "doctrine/annotations": { - "version": "2.0", + "version": "1.0", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "1.10", - "ref": "64d8583af5ea57b7afa4aba4b159907f3a148b05" - } + "branch": "master", + "version": "1.0", + "ref": "a2759dd6123694c8d901d0ec80006e044c2e6457" + }, + "files": [ + "config/routes/annotations.yaml" + ] + }, + "doctrine/cache": { + "version": "1.10.2" + }, + "doctrine/collections": { + "version": "1.6.7" + }, + "doctrine/common": { + "version": "2.13.3" + }, + "doctrine/data-fixtures": { + "version": "1.4.4" + }, + "doctrine/dbal": { + "version": "2.10.3" + }, + "doctrine/deprecations": { + "version": "v0.5.3" }, "doctrine/doctrine-bundle": { - "version": "2.10", + "version": "1.12", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "2.10", - "ref": "e025a6cb69b195970543820b2f18ad21724473fa" + "branch": "master", + "version": "1.12", + "ref": "b11d5292f574a9cd092d506c899d05c79cf4d613" }, "files": [ "config/packages/doctrine.yaml", + "config/packages/prod/doctrine.yaml", "src/Entity/.gitignore", "src/Repository/.gitignore" ] }, "doctrine/doctrine-migrations-bundle": { - "version": "3.2", + "version": "2.2", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "3.1", - "ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33" + "branch": "master", + "version": "2.2", + "ref": "baaa439e3e3179e69e3da84b671f0a3e4a2f56ad" }, "files": [ "config/packages/doctrine_migrations.yaml", "migrations/.gitignore" ] }, + "doctrine/event-manager": { + "version": "1.1.1" + }, + "doctrine/inflector": { + "version": "1.3.1" + }, + "doctrine/instantiator": { + "version": "1.3.1" + }, + "doctrine/lexer": { + "version": "1.2.1" + }, + "doctrine/migrations": { + "version": "3.0.1" + }, + "doctrine/orm": { + "version": "v2.7.3" + }, + "doctrine/persistence": { + "version": "1.3.8" + }, + "doctrine/sql-formatter": { + "version": "1.1.1" + }, + "egulias/email-validator": { + "version": "2.1.19" + }, + "enshrined/svg-sanitize": { + "version": "0.16.0" + }, + "fakerphp/faker": { + "version": "v1.12.0" + }, + "friends-of-behat/mink": { + "version": "v1.8.0" + }, + "friends-of-behat/mink-browserkit-driver": { + "version": "v1.4.0" + }, + "friends-of-behat/mink-debug-extension": { + "version": "v2.0.0" + }, + "friends-of-behat/mink-extension": { + "version": "v2.4.0" + }, + "friends-of-behat/page-object-extension": { + "version": "v0.3.1" + }, "friends-of-behat/symfony-extension": { - "version": "2.4", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "2.0", - "ref": "1e012e04f573524ca83795cd19df9ea690adb604" - } - }, - "friendsofsymfony/rest-bundle": { - "version": "3.5", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "3.0", - "ref": "3762cc4e4f2d6faabeca5a151b41c8c791bd96e5" - } - }, - "hwi/oauth-bundle": { "version": "2.0", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "0.6", - "ref": "18ce21f16066cccfa0803c9e846a2e4f4bec92ab" + "branch": "master", + "version": "2.0", + "ref": "3d21344765fd3440a85bdd27d4cada186ec628bd" } }, - "jms/serializer-bundle": { - "version": "4.2", + "friends-of-behat/variadic-extension": { + "version": "v1.3.0" + }, + "friendsofphp/proxy-manager-lts": { + "version": "v1.0.2" + }, + "friendsofsymfony/rest-bundle": { + "version": "2.2", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "4.0", - "ref": "cc04e10cf7171525b50c18b36004edf64cb478be" + "branch": "master", + "version": "2.2", + "ref": "cad41ef93d6150067ae2bb3c7fd729492dff6f0a" } }, + "gedmo/doctrine-extensions": { + "version": "v2.4.42" + }, + "guzzlehttp/guzzle": { + "version": "6.5.5" + }, + "guzzlehttp/promises": { + "version": "v1.3.1" + }, + "guzzlehttp/psr7": { + "version": "1.6.1" + }, + "hamcrest/hamcrest-php": { + "version": "v2.0.1" + }, + "hwi/oauth-bundle": { + "version": "0.6", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "0.6", + "ref": "20cacc9b2da49d96ea55c8a8dd31324c5be88bc9" + } + }, + "imagine/imagine": { + "version": "1.2.3" + }, + "instaclick/php-webdriver": { + "version": "1.4.7" + }, + "jms/metadata": { + "version": "1.7.0" + }, + "jms/serializer": { + "version": "1.14.1" + }, + "jms/serializer-bundle": { + "version": "2.0", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "2.0", + "ref": "fe60ce509ef04a3f40da96e3979bc8d9b13b2372" + } + }, + "knplabs/gaufrette": { + "version": "v0.8.3" + }, "knplabs/knp-gaufrette-bundle": { - "version": "v0.8.0" + "version": "v0.7.1" + }, + "knplabs/knp-menu": { + "version": "v3.1.2" }, "knplabs/knp-menu-bundle": { - "version": "v3.2.0" + "version": "v3.0.0" + }, + "laminas/laminas-code": { + "version": "3.5.1" + }, + "laminas/laminas-stdlib": { + "version": "3.3.1" + }, + "lchrusciel/api-test-case": { + "version": "v5.0.0" + }, + "lcobucci/clock": { + "version": "2.0.0" + }, + "lcobucci/jwt": { + "version": "3.3.1" }, "league/flysystem-bundle": { "version": "2.4", @@ -107,233 +270,456 @@ "var/storage/.gitignore" ] }, + "league/uri": { + "version": "5.3.0" + }, + "league/uri-components": { + "version": "1.8.2" + }, + "league/uri-interfaces": { + "version": "1.1.1" + }, "lexik/jwt-authentication-bundle": { - "version": "2.17", + "version": "2.5", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", + "branch": "master", "version": "2.5", - "ref": "e9481b233a11ef7e15fe055a2b21fd3ac1aa2bb7" + "ref": "5b2157bcd5778166a5696e42f552ad36529a07a6" }, "files": [ "config/packages/lexik_jwt_authentication.yaml" ] }, "liip/imagine-bundle": { - "version": "2.12", + "version": "1.8", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", + "branch": "master", "version": "1.8", - "ref": "d1227d002b70d1a1f941d91845fcd7ac7fbfc929" + "ref": "5a5bdc2d0e2533ed6935d5ae562f2b318a8fc1ee" } }, + "marcj/topsort": { + "version": "1.1.0" + }, + "matthiasnoback/symfony-config-test": { + "version": "4.2.0" + }, + "matthiasnoback/symfony-dependency-injection-test": { + "version": "4.1.1" + }, + "mikey179/vfsstream": { + "version": "v1.6.8" + }, + "mockery/mockery": { + "version": "1.4.2" + }, + "monolog/monolog": { + "version": "1.25.5" + }, + "myclabs/deep-copy": { + "version": "1.10.1" + }, + "namshi/jose": { + "version": "7.2.3" + }, "nelmio/alice": { - "version": "3.12", + "version": "3.2", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "3.3", - "ref": "42b52d2065dc3fde27912d502c18ca1926e35ae2" + "branch": "master", + "version": "3.2", + "ref": "0b9900ece737bec7752e4155c0164639dd9b0cb0" }, "files": [ - "config/packages/nelmio_alice.yaml" + "config/packages/dev/nelmio_alice.yaml", + "config/packages/test/nelmio_alice.yaml" ] }, + "nikic/php-parser": { + "version": "v4.6.0" + }, "nyholm/psr7": { - "version": "1.8", + "version": "1.6", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", "version": "1.0", - "ref": "4a8c0345442dcca1d8a2c65633dcf0285dd5a5a2" + "ref": "0cd4d2d0e7f646fda75f9944f747a56e6ed13d4c" }, "files": [ "config/packages/nyholm_psr7.yaml" ] }, + "openlss/lib-array2xml": { + "version": "1.0.0" + }, + "pagerfanta/pagerfanta": { + "version": "v3.5.2" + }, + "payum/iso4217": { + "version": "1.0.1" + }, "payum/payum-bundle": { - "version": "2.5", + "version": "2.4", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", + "branch": "master", "version": "2.4", - "ref": "518ac22defa04a8a1d82479ed362e2921487adf0" + "ref": "72ad834a0f4a99175beddb5e2d049136f4a50a67" } }, + "phar-io/manifest": { + "version": "1.0.3" + }, + "phar-io/version": { + "version": "2.0.1" + }, + "php-http/message": { + "version": "1.7.0" + }, + "php-http/message-factory": { + "version": "v1.0.2" + }, + "phparkitect/phparkitect": { + "version": "0.2.9" + }, + "phpdocumentor/reflection-common": { + "version": "1.0.1" + }, + "phpdocumentor/reflection-docblock": { + "version": "4.3.0" + }, + "phpdocumentor/type-resolver": { + "version": "0.4.0" + }, + "phpspec/php-diff": { + "version": "v1.1.0" + }, + "phpspec/phpspec": { + "version": "4.3.1" + }, + "phpspec/prophecy": { + "version": "1.8.0" + }, + "phpstan/phpdoc-parser": { + "version": "0.4.9" + }, "phpstan/phpstan": { - "version": "1.10", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "1.0", - "ref": "f10b8054de1a94a3b9e8806a6453fd5c98491c44" - } + "version": "0.12.29" + }, + "phpstan/phpstan-doctrine": { + "version": "0.10" + }, + "phpstan/phpstan-webmozart-assert": { + "version": "1.1.2" + }, + "phpunit/php-code-coverage": { + "version": "5.3.2" + }, + "phpunit/php-file-iterator": { + "version": "1.4.5" + }, + "phpunit/php-text-template": { + "version": "1.2.1" + }, + "phpunit/php-timer": { + "version": "1.0.9" + }, + "phpunit/php-token-stream": { + "version": "2.0.2" }, "phpunit/phpunit": { - "version": "9.6", + "version": "4.7", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "9.6", - "ref": "7364a21d87e658eb363c5020c072ecfdc12e2326" - }, - "files": [ - ".env.test", - "phpunit.xml.dist", - "tests/bootstrap.php" - ] - }, - "sonata-project/block-bundle": { - "version": "5.0", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "4.11", - "ref": "b4edd2a1e6ac1827202f336cac2771cb529de542" + "branch": "master", + "version": "4.7", + "ref": "c276fa48d4713de91eb410289b3b1834acb7e403" } }, + "polishsymfonycommunity/symfony-mocker-container": { + "version": "v1.0.2" + }, + "psr/cache": { + "version": "1.0.1" + }, + "psr/container": { + "version": "1.0.0" + }, + "psr/event-dispatcher": { + "version": "1.0.0" + }, + "psr/http-client": { + "version": "1.0.1" + }, + "psr/http-message": { + "version": "1.0.1" + }, + "psr/link": { + "version": "1.0.0" + }, + "psr/log": { + "version": "1.0.2" + }, + "ralouphie/getallheaders": { + "version": "3.0.3" + }, + "ramsey/uuid": { + "version": "3.8.0" + }, + "rector/rector": { + "version": "0.11.52" + }, + "sebastian/code-unit-reverse-lookup": { + "version": "1.0.1" + }, + "sebastian/comparator": { + "version": "2.1.3" + }, + "sebastian/diff": { + "version": "2.0.1" + }, + "sebastian/environment": { + "version": "3.1.0" + }, + "sebastian/exporter": { + "version": "3.1.0" + }, + "sebastian/global-state": { + "version": "2.0.0" + }, + "sebastian/object-enumerator": { + "version": "3.0.3" + }, + "sebastian/object-reflector": { + "version": "1.1.1" + }, + "sebastian/recursion-context": { + "version": "3.0.0" + }, + "sebastian/resource-operations": { + "version": "1.0.0" + }, + "sebastian/type": { + "version": "1.1.3" + }, + "sebastian/version": { + "version": "2.0.1" + }, + "slevomat/coding-standard": { + "version": "4.6.3" + }, + "sonata-project/block-bundle": { + "version": "3.12.1" + }, + "sonata-project/cache": { + "version": "2.0.1" + }, "sonata-project/form-extensions": { - "version": "2.0", + "version": "1.0", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "1.4", - "ref": "9c8a1e8ce2b1f215015ed16652c4ed18eb5867fd" + "branch": "master", + "version": "1.0", + "ref": "8273133183506fe6ec66895e8890227b0dfba1c7" } }, "squizlabs/php_codesniffer": { - "version": "3.7", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "3.6", - "ref": "1019e5c08d4821cb9b77f4891f8e9c31ff20ac6f" - } + "version": "3.3.1" }, "stof/doctrine-extensions-bundle": { - "version": "1.7", + "version": "1.2", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", + "branch": "master", "version": "1.2", - "ref": "e805aba9eff5372e2d149a9ff56566769e22819d" + "ref": "6c1ceb662f8997085f739cd089bfbef67f245983" } }, - "sylius-labs/doctrine-migrations-extra-bundle": { - "version": "v0.2.0" + "stripe/stripe-php": { + "version": "v4.13.0" }, - "sylius/fixtures-bundle": { - "version": "v1.8.0" + "sylius-labs/association-hydrator": { + "version": "v1.1.0" }, - "sylius/grid-bundle": { - "version": "v1.12.0" - }, - "sylius/mailer-bundle": { + "sylius-labs/coding-standard": { "version": "v2.0.0" }, + "sylius-labs/doctrine-migrations-extra-bundle": { + "version": "v0.1.3" + }, + "sylius-labs/polyfill-symfony-event-dispatcher": { + "version": "v1.0.0" + }, + "sylius-labs/polyfill-symfony-framework-bundle": { + "version": "v1.0.0" + }, + "sylius-labs/polyfill-symfony-security": { + "version": "v1.0.0" + }, + "sylius/fixtures-bundle": { + "version": "v1.4.1" + }, + "sylius/grid-bundle": { + "version": "v1.7.5" + }, + "sylius/mailer-bundle": { + "version": "v1.5.1" + }, + "sylius/registry": { + "version": "v1.4.0" + }, "sylius/resource-bundle": { - "version": "1.10", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "1.9", - "ref": "ee21c1fc90778f4b01c20e72c320cc34f8839c1e" - } + "version": "v1.6.4" }, "sylius/theme-bundle": { - "version": "v2.3.0" + "version": "v1.4.2" + }, + "sylius/twig-hooks": { + "version": "dev-main" + }, + "symfony/asset": { + "version": "v4.1.3" + }, + "symfony/browser-kit": { + "version": "v4.1.3" + }, + "symfony/cache": { + "version": "v4.1.3" + }, + "symfony/cache-contracts": { + "version": "v2.1.3" + }, + "symfony/config": { + "version": "v4.1.3" }, "symfony/console": { - "version": "6.3", + "version": "3.3", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "5.3", - "ref": "da0c8be8157600ad34f10ff0c9cc91232522e047" - }, - "files": [ - "bin/console" - ] + "branch": "master", + "version": "3.3", + "ref": "e3868d2f4a5104f19f844fe551099a00c6562527" + } + }, + "symfony/css-selector": { + "version": "v4.1.3" }, "symfony/debug-bundle": { - "version": "6.3", + "version": "4.1", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "5.3", - "ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b" - }, - "files": [ - "config/packages/debug.yaml" - ] + "branch": "master", + "version": "4.1", + "ref": "f8863cbad2f2e58c4b65fa1eac892ab189971bea" + } + }, + "symfony/dependency-injection": { + "version": "v4.1.3" + }, + "symfony/deprecation-contracts": { + "version": "v2.1.2" + }, + "symfony/doctrine-bridge": { + "version": "v4.1.3" + }, + "symfony/dom-crawler": { + "version": "v4.1.3" + }, + "symfony/dotenv": { + "version": "v4.1.3" + }, + "symfony/error-handler": { + "version": "v4.4.13" + }, + "symfony/event-dispatcher": { + "version": "v4.1.3" + }, + "symfony/event-dispatcher-contracts": { + "version": "v1.1.9" + }, + "symfony/expression-language": { + "version": "v4.1.3" + }, + "symfony/filesystem": { + "version": "v4.1.3" + }, + "symfony/finder": { + "version": "v4.1.3" }, "symfony/flex": { - "version": "2.3", + "version": "1.0", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", + "branch": "master", "version": "1.0", - "ref": "146251ae39e06a95be0fe3d13c807bcf3938b172" - }, - "files": [ - ".env" - ] + "ref": "e921bdbfe20cdefa3b82f379d1cd36df1bc8d115" + } + }, + "symfony/form": { + "version": "v4.1.3" }, "symfony/framework-bundle": { - "version": "6.3", + "version": "3.3", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.2", - "ref": "af47254c5e4cd543e6af3e4508298ffebbdaddd3" - }, - "files": [ - "config/packages/cache.yaml", - "config/packages/framework.yaml", - "config/preload.php", - "config/routes/framework.yaml", - "config/services.yaml", - "public/index.php", - "src/Controller/.gitignore", - "src/Kernel.php" - ] + "branch": "master", + "version": "3.3", + "ref": "87c585d24de9f43bca80ebcfd5cf5cb39445d95f" + } + }, + "symfony/http-foundation": { + "version": "v4.1.3" + }, + "symfony/http-kernel": { + "version": "v4.1.3" + }, + "symfony/intl": { + "version": "v4.1.3" }, "symfony/mailer": { - "version": "6.3", + "version": "5.4", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", "version": "4.3", - "ref": "2bf89438209656b85b9a49238c4467bff1b1f939" + "ref": "97a61eabb351d7f6cb7702039bcfe07fe9d7e03c" }, "files": [ "config/packages/mailer.yaml" ] }, "symfony/messenger": { - "version": "6.3", + "version": "4.3", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.0", - "ref": "ba1ac4e919baba5644d31b57a3284d6ba12d52ee" + "branch": "master", + "version": "4.3", + "ref": "8a2675c061737658bed85102e9241c752620e575" }, "files": [ "config/packages/messenger.yaml" ] }, + "symfony/mime": { + "version": "v5.1.5" + }, + "symfony/monolog-bridge": { + "version": "v4.1.3" + }, "symfony/monolog-bundle": { - "version": "3.8", + "version": "3.1", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "3.7", - "ref": "213676c4ec929f046dfde5ea8e97625b81bc0578" - }, - "files": [ - "config/packages/monolog.yaml" - ] + "branch": "master", + "version": "3.1", + "ref": "18ebf5a940573a20de06f9c4060101eeb438cf3d" + } + }, + "symfony/options-resolver": { + "version": "v4.1.3" }, "symfony/panther": { "version": "2.1", @@ -344,89 +730,216 @@ "ref": "292a3236e81f55b545b09b9954ab097248972ab3" } }, + "symfony/password-hasher": { + "version": "v5.4.3" + }, + "symfony/polyfill-ctype": { + "version": "v1.9.0" + }, + "symfony/polyfill-iconv": { + "version": "v1.9.0" + }, + "symfony/polyfill-intl-grapheme": { + "version": "v1.22.0" + }, + "symfony/polyfill-intl-icu": { + "version": "v1.9.0" + }, + "symfony/polyfill-intl-idn": { + "version": "v1.18.1" + }, + "symfony/polyfill-intl-normalizer": { + "version": "v1.17.0" + }, + "symfony/polyfill-mbstring": { + "version": "v1.9.0" + }, + "symfony/polyfill-php56": { + "version": "v1.15.0" + }, + "symfony/polyfill-php72": { + "version": "v1.18.1" + }, + "symfony/polyfill-php80": { + "version": "v1.15.0" + }, + "symfony/process": { + "version": "v4.4.13" + }, + "symfony/property-access": { + "version": "v4.4.13" + }, + "symfony/property-info": { + "version": "v5.0.7" + }, + "symfony/proxy-manager-bridge": { + "version": "v4.4.13" + }, "symfony/routing": { - "version": "6.3", + "version": "4.2", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.2", - "ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6" + "branch": "master", + "version": "4.2", + "ref": "683dcb08707ba8d41b7e34adb0344bfd68d248a7" }, "files": [ + "config/packages/prod/routing.yaml", "config/packages/routing.yaml", "config/routes.yaml" ] }, "symfony/security-bundle": { - "version": "6.3", + "version": "4.4", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.0", - "ref": "8a5b112826f7d3d5b07027f93786ae11a1c7de48" + "branch": "master", + "version": "4.4", + "ref": "7b4408dc203049666fe23fabed23cbadc6d8440f" }, "files": [ "config/packages/security.yaml" ] }, - "symfony/translation": { - "version": "6.3", + "symfony/security-core": { + "version": "v4.4.13" + }, + "symfony/security-csrf": { + "version": "v4.4.13" + }, + "symfony/security-http": { + "version": "v4.4.13" + }, + "symfony/serializer": { + "version": "v5.0.7" + }, + "symfony/service-contracts": { + "version": "v2.1.3" + }, + "symfony/stimulus-bundle": { + "version": "2.12", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", - "version": "6.3", - "ref": "64fe617084223633e1dedf9112935d8c95410d3e" + "version": "2.8", + "ref": "9e33a8a3794b603fb4be6c04ee5ecab901ce549e" + } + }, + "symfony/stopwatch": { + "version": "v5.1.5" + }, + "symfony/string": { + "version": "v5.2.1" + }, + "symfony/templating": { + "version": "v4.4.13" + }, + "symfony/thanks": { + "version": "v1.2.9" + }, + "symfony/translation": { + "version": "3.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.3", + "ref": "2ad9d2545bce8ca1a863e50e92141f0b9d87ffcd" }, "files": [ "config/packages/translation.yaml", "translations/.gitignore" ] }, + "symfony/translation-contracts": { + "version": "v1.1.9" + }, + "symfony/twig-bridge": { + "version": "v4.4.13" + }, "symfony/twig-bundle": { - "version": "6.3", + "version": "4.4", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.3", - "ref": "b7772eb20e92f3fb4d4fe756e7505b4ba2ca1a2c" + "branch": "master", + "version": "4.4", + "ref": "15a41bbd66a1323d09824a189b485c126bbefa51" }, "files": [ + "config/packages/test/twig.yaml", "config/packages/twig.yaml", "templates/base.html.twig" ] }, - "symfony/validator": { - "version": "6.3", + "symfony/ux-autocomplete": { + "version": "2.9999999", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", - "version": "5.3", - "ref": "c32cfd98f714894c4f128bb99aa2530c1227603c" + "version": "2.6", + "ref": "07d9602b7231ba355f484305d6cea58310c01741" }, "files": [ + "config/routes/ux_autocomplete.yaml" + ] + }, + "symfony/ux-live-component": { + "version": "2.12", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.6", + "ref": "73e69baf18f47740d6f58688c5464b10cdacae06" + }, + "files": [ + "config/routes/ux_live_component.yaml" + ] + }, + "symfony/ux-twig-component": { + "version": "v2.11.2" + }, + "symfony/validator": { + "version": "4.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "4.3", + "ref": "d902da3e4952f18d3bf05aab29512eb61cabd869" + }, + "files": [ + "config/packages/test/validator.yaml", "config/packages/validator.yaml" ] }, + "symfony/var-dumper": { + "version": "v5.1.5" + }, + "symfony/var-exporter": { + "version": "v5.1.5" + }, + "symfony/web-link": { + "version": "v5.0.7" + }, "symfony/web-profiler-bundle": { - "version": "6.3", + "version": "3.3", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", - "version": "6.1", - "ref": "e42b3f0177df239add25373083a564e5ead4e13a" + "branch": "master", + "version": "3.3", + "ref": "6bdfa1a95f6b2e677ab985cd1af2eae35d62e0f6" }, "files": [ - "config/packages/web_profiler.yaml", - "config/routes/web_profiler.yaml" + "config/packages/dev/web_profiler.yaml", + "config/packages/test/web_profiler.yaml", + "config/routes/dev/web_profiler.yaml" ] }, "symfony/webpack-encore-bundle": { - "version": "1.17", + "version": "1.15", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", "version": "1.10", - "ref": "eff2e505d4557c967b6710fe06bd947ba555cae5" + "ref": "51fec8b86251b9bfc126ebc1827c9a02fa81ee81" }, "files": [ "assets/app.js", @@ -440,7 +953,7 @@ ] }, "symfony/workflow": { - "version": "6.3", + "version": "6.4", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", @@ -451,25 +964,58 @@ "config/packages/workflow.yaml" ] }, + "symfony/yaml": { + "version": "v4.4.13" + }, + "symplify/easy-coding-standard": { + "version": "v8.1.19" + }, + "textalk/websocket": { + "version": "1.2.0" + }, "theofidry/alice-data-fixtures": { - "version": "1.6", + "version": "1.0", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "main", + "branch": "master", "version": "1.0", "ref": "fe5a50faf580eb58f08ada2abe8afbd2d4941e05" } }, + "theseer/tokenizer": { + "version": "1.2.0" + }, + "twig/extra-bundle": { + "version": "v3.9.3" + }, + "twig/twig": { + "version": "v2.13.1" + }, + "webmozart/assert": { + "version": "1.9.1" + }, + "willdurand/hateoas": { + "version": "2.12.0" + }, "willdurand/hateoas-bundle": { - "version": "2.5", + "version": "1.4", "recipe": { "repo": "github.com/symfony/recipes-contrib", - "branch": "main", - "version": "2.0", + "branch": "master", + "version": "1.4", "ref": "34df072c6edaa61ae19afb2f3a239f272fecab87" } }, + "willdurand/jsonp-callback-validator": { + "version": "v1.1.0" + }, + "willdurand/negotiation": { + "version": "v2.3.1" + }, + "winzou/state-machine": { + "version": "0.3.3" + }, "winzou/state-machine-bundle": { - "version": "0.6.0" + "version": "0.3.2" } } diff --git a/webpack.config.js b/webpack.config.js index 8b1ebe62cd..9490ea0f7c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,8 @@ const path = require('path'); const Encore = require('@symfony/webpack-encore'); +const SyliusAdmin = require('@sylius-ui/admin'); + const uiBundleScripts = path.resolve(__dirname, 'src/Sylius/Bundle/UiBundle/Resources/private/js/'); const uiBundleResources = path.resolve(__dirname, 'src/Sylius/Bundle/UiBundle/Resources/private/'); @@ -23,22 +25,6 @@ shopConfig.name = 'shop'; Encore.reset(); -// Admin config -Encore - .setOutputPath('public/build/admin/') - .setPublicPath('/build/admin') - .addEntry('admin-entry', './src/Sylius/Bundle/AdminBundle/Resources/private/entry.js') - .disableSingleRuntimeChunk() - .cleanupOutputBeforeBuild() - .enableSourceMaps(!Encore.isProduction()) - .enableVersioning(Encore.isProduction()) - .enableSassLoader(); - -const adminConfig = Encore.getWebpackConfig(); - -adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts; -adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; -adminConfig.externals = Object.assign({}, adminConfig.externals, { window: 'window', document: 'document' }); -adminConfig.name = 'admin'; +const adminConfig = SyliusAdmin.getWebpackConfig(path.resolve(__dirname)); module.exports = [shopConfig, adminConfig];