Issue #3025870 by tim.plunkett, Kristen Pol, xjm: Cancelling changes in the Layout Builder UI should use a confirmation form
parent
b0a63891a7
commit
94ac341ed9
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\layout_builder\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
|
||||
use Drupal\layout_builder\SectionStorageInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Discards any pending changes to the layout.
|
||||
*/
|
||||
class DiscardLayoutChangesForm extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The layout tempstore repository.
|
||||
*
|
||||
* @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface
|
||||
*/
|
||||
protected $layoutTempstoreRepository;
|
||||
|
||||
/**
|
||||
* The messenger service.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* The section storage.
|
||||
*
|
||||
* @var \Drupal\layout_builder\SectionStorageInterface
|
||||
*/
|
||||
protected $sectionStorage;
|
||||
|
||||
/**
|
||||
* Constructs a new DiscardLayoutChangesForm.
|
||||
*
|
||||
* @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository
|
||||
* The layout tempstore repository.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger service.
|
||||
*/
|
||||
public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger) {
|
||||
$this->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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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",
|
||||
];
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
];
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue