diff --git a/core/modules/layout_builder/layout_builder.post_update.php b/core/modules/layout_builder/layout_builder.post_update.php index 0ee7390dd59..a0ada029ac5 100644 --- a/core/modules/layout_builder/layout_builder.post_update.php +++ b/core/modules/layout_builder/layout_builder.post_update.php @@ -72,3 +72,10 @@ function layout_builder_post_update_section_storage_context_definitions() { function layout_builder_post_update_overrides_view_mode_annotation() { // Empty post-update hook. } + +/** + * Clear caches due to routing changes for the new discard changes form. + */ +function layout_builder_post_update_cancel_link_to_discard_changes_form() { + // Empty post-update hook. +} diff --git a/core/modules/layout_builder/src/Controller/LayoutBuilderController.php b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php index f442ba52b9e..90104848fdc 100644 --- a/core/modules/layout_builder/src/Controller/LayoutBuilderController.php +++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php @@ -344,21 +344,4 @@ class LayoutBuilderController implements ContainerInjectionInterface { return new RedirectResponse($section_storage->getRedirectUrl()->setAbsolute()->toString()); } - /** - * Cancels the layout. - * - * @param \Drupal\layout_builder\SectionStorageInterface $section_storage - * The section storage. - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - * A redirect response. - */ - public function cancelLayout(SectionStorageInterface $section_storage) { - $this->layoutTempstoreRepository->delete($section_storage); - - $this->messenger->addMessage($this->t('The changes to the layout have been discarded.')); - - return new RedirectResponse($section_storage->getRedirectUrl()->setAbsolute()->toString()); - } - } diff --git a/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php b/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php new file mode 100644 index 00000000000..311bc7df3ae --- /dev/null +++ b/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php @@ -0,0 +1,101 @@ +layoutTempstoreRepository = $layout_tempstore_repository; + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('layout_builder.tempstore_repository'), + $container->get('messenger') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'layout_builder_discard_changes'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->t('Are you sure you want to discard your layout changes?'); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return $this->sectionStorage->getRedirectUrl(); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) { + $this->sectionStorage = $section_storage; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->layoutTempstoreRepository->delete($this->sectionStorage); + + $this->messenger->addMessage($this->t('The changes to the layout have been discarded.')); + + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php index b3d40b38bd1..3c3c95777fa 100644 --- a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php +++ b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php @@ -210,9 +210,9 @@ class DefaultsSectionStorage extends SectionStorageBase implements ContainerFact 'title' => $this->t('Save Layout'), 'parent_id' => "layout_builder_ui:layout_builder.defaults.$entity_type_id.view", ]; - $local_tasks["layout_builder.defaults.$entity_type_id.cancel"] = $base_plugin_definition + [ - 'route_name' => "layout_builder.defaults.$entity_type_id.cancel", - 'title' => $this->t('Cancel Layout'), + $local_tasks["layout_builder.defaults.$entity_type_id.discard_changes"] = $base_plugin_definition + [ + 'route_name' => "layout_builder.defaults.$entity_type_id.discard_changes", + 'title' => $this->t('Discard changes'), 'weight' => 5, 'parent_id' => "layout_builder_ui:layout_builder.defaults.$entity_type_id.view", ]; diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php index 7726a455b81..fc9e9a3cf8d 100644 --- a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php +++ b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php @@ -233,9 +233,9 @@ class OverridesSectionStorage extends SectionStorageBase implements ContainerFac 'parent_id' => "layout_builder_ui:layout_builder.overrides.$entity_type_id.view", 'cache_contexts' => ['layout_builder_is_active:' . $entity_type_id], ]; - $local_tasks["layout_builder.overrides.$entity_type_id.cancel"] = $base_plugin_definition + [ - 'route_name' => "layout_builder.overrides.$entity_type_id.cancel", - 'title' => $this->t('Cancel Layout'), + $local_tasks["layout_builder.overrides.$entity_type_id.discard_changes"] = $base_plugin_definition + [ + 'route_name' => "layout_builder.overrides.$entity_type_id.discard_changes", + 'title' => $this->t('Discard changes'), 'parent_id' => "layout_builder_ui:layout_builder.overrides.$entity_type_id.view", 'weight' => 5, 'cache_contexts' => ['layout_builder_is_active:' . $entity_type_id], diff --git a/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php index d06b95324b9..87fc0a23928 100644 --- a/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php +++ b/core/modules/layout_builder/src/Routing/LayoutBuilderRoutesTrait.php @@ -77,13 +77,13 @@ trait LayoutBuilderRoutesTrait { ->setOptions($options); $collection->add("$route_name_prefix.save", $route); - $cancel_defaults = $defaults; - $cancel_defaults['_controller'] = '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout'; - $route = (new Route("$path/cancel")) - ->setDefaults($cancel_defaults) + $discard_changes_defaults = $defaults; + $discard_changes_defaults['_form'] = '\Drupal\layout_builder\Form\DiscardLayoutChangesForm'; + $route = (new Route("$path/discard-changes")) + ->setDefaults($discard_changes_defaults) ->setRequirements($requirements) ->setOptions($options); - $collection->add("$route_name_prefix.cancel", $route); + $collection->add("$route_name_prefix.discard_changes", $route); if (is_subclass_of($definition->getClass(), OverridesSectionStorageInterface::class)) { $revert_defaults = $defaults; diff --git a/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/SimpleConfigSectionStorage.php b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/SimpleConfigSectionStorage.php index 7e15336519c..638d1fec6f2 100644 --- a/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/SimpleConfigSectionStorage.php +++ b/core/modules/layout_builder/tests/modules/layout_builder_test/src/Plugin/SectionStorage/SimpleConfigSectionStorage.php @@ -160,9 +160,9 @@ class SimpleConfigSectionStorage extends ContextAwarePluginBase implements Secti 'title' => $this->t('Save Layout'), 'parent_id' => "layout_builder_ui:layout_builder.$type.view", ]; - $local_tasks["layout_builder.$type.cancel"] = $base_plugin_definition + [ - 'route_name' => "layout_builder.$type.cancel", - 'title' => $this->t('Cancel Layout'), + $local_tasks["layout_builder.$type.discard_changes"] = $base_plugin_definition + [ + 'route_name' => "layout_builder.$type.discard_changes", + 'title' => $this->t('Discard changes'), 'parent_id' => "layout_builder_ui:layout_builder.$type.view", 'weight' => 5, ]; diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php index ee15bdfc767..b1ddaa7f0f1 100644 --- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php @@ -306,7 +306,8 @@ class LayoutBuilderTest extends BrowserTestBase { $this->clickLink('Manage layout'); // Confirm the body field only is shown once. $assert_session->elementsCount('css', '.field--name-body', 1); - $this->clickLink('Cancel Layout'); + $this->clickLink('Discard changes'); + $page->pressButton('Confirm'); $this->clickLink('Teaser'); // Enabling Layout Builder for the default mode does not affect the teaser. @@ -321,7 +322,8 @@ class LayoutBuilderTest extends BrowserTestBase { $assert_session->elementsCount('css', '.field--name-body', 1); // Enable a disabled view mode. - $page->clickLink('Cancel Layout'); + $page->clickLink('Discard changes'); + $page->pressButton('Confirm'); $assert_session->addressEquals("$field_ui_prefix/display/teaser"); $page->clickLink('Default'); $assert_session->addressEquals("$field_ui_prefix/display"); @@ -451,7 +453,8 @@ class LayoutBuilderTest extends BrowserTestBase { $assert_session->pageTextContains('This is the default view mode'); $this->drupalGet('node/1/layout'); $assert_session->pageTextContains('This is the default view mode'); - $this->clickLink('Cancel Layout'); + $this->clickLink('Discard changes'); + $page->pressButton('Confirm'); // Enable the full view mode and customize it. $this->drupalPostForm("$field_ui_prefix/display/default", ['display_modes_custom[full]' => TRUE], 'Save'); @@ -470,7 +473,8 @@ class LayoutBuilderTest extends BrowserTestBase { $assert_session->pageTextContains('This is the full view mode'); $this->drupalGet('node/1/layout'); $assert_session->pageTextContains('This is the full view mode'); - $this->clickLink('Cancel Layout'); + $this->clickLink('Discard changes'); + $page->pressButton('Confirm'); // Disable the full view mode, the default should be used again. $this->drupalPostForm("$field_ui_prefix/display/default", ['display_modes_custom[full]' => FALSE], 'Save'); @@ -478,7 +482,8 @@ class LayoutBuilderTest extends BrowserTestBase { $assert_session->pageTextContains('This is the default view mode'); $this->drupalGet('node/1/layout'); $assert_session->pageTextContains('This is the default view mode'); - $this->clickLink('Cancel Layout'); + $this->clickLink('Discard changes'); + $page->pressButton('Confirm'); } /** diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php index 4f463192d15..2e702bc60d0 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php @@ -124,7 +124,7 @@ class InlineBlockTest extends InlineBlockTestBase { $page->pressButton($confirm_button_text); } $this->drupalGet('node/1'); - $this->assertEmpty($this->blockStorage->loadMultiple(), 'No entity blocks were created when layout is canceled.'); + $this->assertEmpty($this->blockStorage->loadMultiple(), 'No entity blocks were created when layout changes are discarded.'); $assert_session->pageTextNotContains('The block body'); $this->drupalGet('node/1/layout'); @@ -150,10 +150,10 @@ class InlineBlockTest extends InlineBlockTestBase { $this->drupalGet('node/1'); $blocks = $this->blockStorage->loadMultiple(); - // When reverting or canceling the update block should not be on the page. + // When reverting or discarding the update block should not be on the page. $assert_session->pageTextNotContains('The block updated body'); - if ($operation === 'cancel') { - // When canceling the original block body should appear. + if ($operation === 'discard_changes') { + // When discarding the original block body should appear. $assert_session->pageTextContains('The block body'); $this->assertEquals(count($blocks), 1); @@ -173,10 +173,10 @@ class InlineBlockTest extends InlineBlockTestBase { */ public function layoutNoSaveProvider() { return [ - 'cancel' => [ - 'cancel', - 'Cancel Layout', - NULL, + 'discard_changes' => [ + 'discard_changes', + 'Discard changes', + 'Confirm', ], 'revert' => [ 'revert', diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php index c5510e9d5fc..9dc7dd3e7e2 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php @@ -57,9 +57,10 @@ class LayoutBuilderUiTest extends WebDriverTestBase { 'Save' ); - // Make and then cancel changes. + // Make and then discard changes. $this->assertModifiedLayout(static::FIELD_UI_PREFIX . '/display-layout/default'); - $page->clickLink('Cancel Layout'); + $page->clickLink('Discard changes'); + $page->pressButton('Confirm'); $assert_session->pageTextNotContains('You have unsaved changes.'); // Make and then save changes. diff --git a/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php index ab7b7e8ec0a..9c5e96d4302 100644 --- a/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php +++ b/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php @@ -419,14 +419,14 @@ class DefaultsSectionStorageTest extends UnitTestCase { '_admin_route' => FALSE, ] ), - 'layout_builder.defaults.with_bundle_key.cancel' => new Route( - '/admin/entity/whatever/display-layout/{view_mode_name}/cancel', + 'layout_builder.defaults.with_bundle_key.discard_changes' => new Route( + '/admin/entity/whatever/display-layout/{view_mode_name}/discard-changes', [ 'entity_type_id' => 'with_bundle_key', 'bundle_key' => 'my_bundle_type', 'section_storage_type' => 'defaults', 'section_storage' => '', - '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout', + '_form' => '\Drupal\layout_builder\Form\DiscardLayoutChangesForm', ], [ '_field_ui_view_mode_access' => 'administer with_bundle_key display', @@ -505,13 +505,13 @@ class DefaultsSectionStorageTest extends UnitTestCase { '_admin_route' => FALSE, ] ), - 'layout_builder.defaults.with_bundle_parameter.cancel' => new Route( - '/admin/entity/{bundle}/display-layout/{view_mode_name}/cancel', + 'layout_builder.defaults.with_bundle_parameter.discard_changes' => new Route( + '/admin/entity/{bundle}/display-layout/{view_mode_name}/discard-changes', [ 'entity_type_id' => 'with_bundle_parameter', 'section_storage_type' => 'defaults', 'section_storage' => '', - '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout', + '_form' => '\Drupal\layout_builder\Form\DiscardLayoutChangesForm', ], [ '_field_ui_view_mode_access' => 'administer with_bundle_parameter display', diff --git a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php index 6ea0c4bc434..567648c0d16 100644 --- a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php +++ b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php @@ -343,13 +343,13 @@ class OverridesSectionStorageTest extends UnitTestCase { '_layout_builder' => TRUE, ] ), - 'layout_builder.overrides.with_string_id.cancel' => new Route( - '/entity/{entity}/layout/cancel', + 'layout_builder.overrides.with_string_id.discard_changes' => new Route( + '/entity/{entity}/layout/discard-changes', [ 'entity_type_id' => 'with_string_id', 'section_storage_type' => 'overrides', 'section_storage' => '', - '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout', + '_form' => '\Drupal\layout_builder\Form\DiscardLayoutChangesForm', ], [ '_has_layout_section' => 'true', @@ -427,13 +427,13 @@ class OverridesSectionStorageTest extends UnitTestCase { '_layout_builder' => TRUE, ] ), - 'layout_builder.overrides.with_integer_id.cancel' => new Route( - '/entity/{entity}/layout/cancel', + 'layout_builder.overrides.with_integer_id.discard_changes' => new Route( + '/entity/{entity}/layout/discard-changes', [ 'entity_type_id' => 'with_integer_id', 'section_storage_type' => 'overrides', 'section_storage' => '', - '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout', + '_form' => '\Drupal\layout_builder\Form\DiscardLayoutChangesForm', ], [ '_has_layout_section' => 'true',