Issue #3025870 by tim.plunkett, Kristen Pol, xjm: Cancelling changes in the Layout Builder UI should use a confirmation form

8.7.x
xjm 2019-01-17 16:27:23 -06:00
parent b0a63891a7
commit 94ac341ed9
12 changed files with 155 additions and 58 deletions

View File

@ -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.
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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",
];

View File

@ -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],

View File

@ -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;

View File

@ -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,
];

View File

@ -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');
}
/**

View File

@ -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',

View File

@ -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.

View File

@ -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',

View File

@ -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',