Problem/Motivation

From #2905922-61: Implementation issue for Layout Builder:

  • Does a layout in progress go into a tempstore like Views? Seems like the kind of thing where it would really suck to lose your work when leaving the page. I couldn't tell whether it did or not when playing with it.
  • On that note, would be good to have a message like "You have unsaved changes" like Views does. Otherwise I can get lost in the page and not know if I actually changed something or not.
  • IANAD (I am not a designer) but it seems like it would be good to have visual feedback on when a layout is saved or not.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#35 2919795-tempstore-35-interdiff.txt2.92 KBtim.plunkett
#35 2919795-tempstore-35.patch11.22 KBtim.plunkett
#35 2919795-tempstore-35-x30.patch13.38 KBtim.plunkett
#34 x30-2919795-34.patch17.5 KBtedbow
#34 interdiff-32-34.txt951 bytestedbow
#32 interdiff-31-32.patch5.87 KBtedbow
#32 x30-2919795-32.patch17.61 KBtedbow
#31 interdiff-29-31.txt1.8 KBtedbow
#31 2919795-31-x30.patch16.07 KBtedbow
#29 interdiff-19-29.txt2.9 KBtedbow
#29 2919795-29-x25.patch15.19 KBtedbow
#19 2919795-tempstore-19-PASS.patch11.4 KBtim.plunkett
#19 2919795-tempstore-19-FAIL.patch6.36 KBtim.plunkett
#18 2919795-tempstore-18.patch5.04 KBtim.plunkett
#18 2919795-tempstore-18-interdiff.txt1.26 KBtim.plunkett
#13 2919795-tempstore-13.patch4.12 KBtim.plunkett
#13 2919795-tempstore-13.patch4.12 KBtim.plunkett
#13 2919795-tempstore-13-interdiff.txt2.07 KBtim.plunkett
#11 2919795-11.patch4.67 KBdead_arm
#11 interdiff_10-11.txt409 bytesdead_arm
#10 2919795-10.patch4.65 KBdead_arm
#10 interdiff_9-10.txt396 bytesdead_arm
#9 interdiff_2919795-9.txt389 bytesdead_arm
#9 2919795-9.patch4.6 KBdead_arm
#9 Screen Shot 2018-08-24 at 1.09.35 PM.png115.11 KBdead_arm
#8 2919795-tempstore-8.patch4.22 KBtim.plunkett
#7 overridden-layout-changes.png103.71 KBdead_arm
#7 Screen Shot 2018-08-24 at 11.41.35 AM.png72.03 KBdead_arm
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tim.plunkett created an issue. See original summary.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tim.plunkett’s picture

Component: layout.module » layout_builder.module

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tim.plunkett’s picture

Issue tags: +sprint
dead_arm’s picture

Issue tags: +MWDS2018
dead_arm’s picture

Does a layout in progress go into a tempstore like Views?
Yes it does, verified by testing using the following steps:

  • Enable layout builder modules
  • Enable the ability to use layout builder for a content type
  • Modify a layout by adding a section, and some additional content, do not click 'Save Layout'
  • Navigate away from the layout configuration to a new page
  • Go back to the layout configuration page and refresh
  • Verify that the unsaved configuration changes are present

Views uses both a message of "You have unsaved changes.", and a state change of adding an asterisk on the display button that is modified and not saved to indicate unsaved configuration changes.

screenshot of views ui

Applying that same idea to the layout builder using the message, and adding an asterisk to the title would like this:

proposed unsaved indicator

tim.plunkett’s picture

Status: Active » Needs review
FileSize
4.22 KB

This does the yellow block part.
It has two classes for the default styling ('messages', 'messages--warning') and one for additional CSS needs ('layout-builder--changed').

Also had to expand LayoutTempstoreRepository to add a has() method, since get() will always return a viable object and cannot be used to check for existence.

dead_arm’s picture

Adding some CSS to adjust spacing.

patch with spacing added

dead_arm’s picture

Adds rtl CSS for the message.

dead_arm’s picture

Adds the inline /* LTR */ comment for the initial CSS change. The 8px value applied for left and right margin alignment styling mimics styling that Seven theme applies to the messages class. The 30px margin bottom value is adopted from the margin bottom of .block-help.

tedbow’s picture

Status: Needs review » Needs work

Great improvement!

  1. +++ b/core/modules/layout_builder/css/layout-builder.css
    @@ -85,3 +85,11 @@
    +[dir="rtl"] .messages {
    +  margin: 0 8px 30px 0;
    +}
    

    This will affect all messages on the page not just layout builder. Maybe add .layout-builder--changed. I think the only thing we target is the #layout-builder which I know we are not supposed to use. Could we put a class on the same element as that id?

    This will be more important after our ancestors commit #77245: Provide a common API for displaying JavaScript messages as there might other messages on other parts of the page we don't want to affect.

  2. +++ b/core/modules/layout_builder/src/Controller/LayoutBuilderController.php
    @@ -90,6 +90,21 @@ public function layout(SectionStorageInterface $section_storage, $is_rebuilding
    +      $output[] = [
    +        '#type' => 'container',
    +        '#attributes' => [
    +          'class' => [
    +            'layout-builder--changed',
    +            'messages',
    +            'messages--warning',
    +          ],
    +        ],
    +        '#children' => $this->t('You have unsaved changes.'),
    +      ];
    

    Why can't we do this

    $this->messenger->addWarning('You have unsaved changes.');
    $output['status_messages'] = [
      '#type' => 'status_messages',
    ];

    This seemed to work

tim.plunkett’s picture

12.2 is a great idea. And we don't even need to manually add it to the markup, it will be duplicated.

And now by using the default styling (instead of copying from Views UI) we don't need custom styling.

tedbow’s picture

Issue tags: +Needs tests

And we don't even need to manually add it to the markup, it will be duplicated.

If we don't add the markup you don't get the message until you reload the page or come back to it because the layout builder is loaded with an ajax replace which doesn't show messages.

If we have the mark up I don't see it duplicated. We need test for this message because right now it doesn't display after you add a block unless you reload the page.

dead_arm’s picture

tim.plunkett’s picture

Status: Needs review » Needs work

NW for the tests

tim.plunkett’s picture

Assigned: Unassigned » tim.plunkett
Issue tags: +Layout Builder stable blocker

Working on this. Also this is a stable blocker.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
1.26 KB
5.04 KB

Not sure how best to test this until #2924201: Resolve random failure in LayoutBuilderTest so that it can be added to HEAD is resolved. Maybe a one-off test is justified.

Either way, here's the fix to allow seeing the message during an AJAX flow without duplicate messages during a regular page load.

tim.plunkett’s picture

Here's a test. Since it's in the wrong namespace but really useful, I repurposed \Drupal\Tests\layout_builder\Functional\LayoutBuilderTest::assertTextAppearsOnce() as \Drupal\Tests\WebAssert::pageTextContainsOnce(), to match the existing \Behat\Mink\WebAssert::pageTextContains()

The FAIL patch is equivalent to the interdiff.


Adding credit for @tedbow for the above review and also the pointer to assertTextAppearsOnce()

The last submitted patch, 19: 2919795-tempstore-19-FAIL.patch, failed testing. View results

jibran’s picture

Status: Needs review » Reviewed & tested by the community

This part of the UI always fascinates me. :D The patch looks ready to me. Screenshots can be seen in #9.

The last submitted patch, 19: 2919795-tempstore-19-FAIL.patch, failed testing. View results

webchick’s picture

Status: Reviewed & tested by the community » Fixed

The patch does what it says on the tin. :) (Well, the yellow message anyway, which I think is sufficient... we don't "asterisk" the title of e.g. nodes or other places, so it would look out of place here.) Thanks for the screenshots and steps to reproduce in #9. SUPER helpful. Test coverage appears to be intact.

Committed and pushed to 8.7.x. Thanks!

  • webchick committed 5781cdb on 8.7.x
    Issue #2919795 by tim.plunkett, dead_arm, tedbow: Add visual hints that...

tim.plunkett credited xjm.

tim.plunkett’s picture

Status: Reviewed & tested by the community » Fixed

Forgot to add @xjm as the entire IS is based on her original feedback.

alexpott’s picture

Status: Fixed » Needs work

Reverting this because unfortunately this caused random fails in Drupal\Tests\layout_builder\FunctionalJavascript\LayoutBuilderUiTest

Drupal\Tests\layout_builder\FunctionalJavascript\LayoutBuilderUiTest::testUnsavedChangesMessage
WebDriver\Exception\UnknownError: unknown error: Element ... is not clickable at point (60, 571). Other element would receive the click: ...
  (Session info: headless chrome=62.0.3202.94)
  (Driver info: chromedriver=2.33.506092 (733a02544d189eeb751fe0d7ddca79a0ee28cce4),platform=Linux 4.9.0-0.bpo.6-amd64 x86_64)

/var/www/html/vendor/instaclick/php-webdriver/lib/WebDriver/Exception.php:155
/var/www/html/vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php:157
/var/www/html/vendor/instaclick/php-webdriver/lib/WebDriver/AbstractWebDriver.php:218
/var/www/html/vendor/instaclick/php-webdriver/lib/WebDriver/Container.php:224
/var/www/html/vendor/behat/mink-selenium2-driver/src/Selenium2Driver.php:775
/var/www/html/vendor/behat/mink-selenium2-driver/src/Selenium2Driver.php:763
/var/www/html/vendor/behat/mink/src/Element/NodeElement.php:153
/var/www/html/vendor/behat/mink/src/Element/TraversableElement.php:73
/var/www/html/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php:88

See https://www.drupal.org/pift-ci-job/1086096 and https://www.drupal.org/pift-ci-job/1086188

  • alexpott committed 31ef300 on 8.7.x
    Revert "Issue #2919795 by tim.plunkett, dead_arm, tedbow: Add visual...
tedbow’s picture

Status: Needs work » Needs review
FileSize
15.19 KB
2.9 KB
  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php
    @@ -0,0 +1,93 @@
    +    $assert_session->assertWaitOnAjaxRequest();
    +    $assert_session->pageTextContainsOnce('You have unsaved changes.');
    +
    +    // Save the changes.
    +    $page->clickLink('Save Layout');
    

    This where it fails. We already do assertWaitOnAjaxRequest() by guess is somehow the off-canvas is still on the page and it is in the way of the "Save layout" link.

    Adding a wait for the link to be gone.

  2. Also adding the no_transitions_css module to avoid these types of problem.
    but also fix that module because it was actually attaching the settings_tray_test_css/drupal.css_fix library. Just a copy and paste error.

Status: Needs review » Needs work

The last submitted patch, 29: 2919795-29-x25.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
16.07 KB
1.8 KB

Ok this is the same random failure problem I was running into in #2957425: Allow the inline creation of non-reusable Custom Blocks in the layout builder

I found this before it was committed and actually working on this random problem here #2977515: [ignore] Test Package manager core merge because the issue was already super long.

For some reason clicking "Save Layout" seem to have no effect.

I made a solution in \Drupal\Tests\layout_builder\FunctionalJavascript\InlineBlockTestBase::assertSaveLayout() with a @todo that we should really redo these tests in nightwatch #2984161: Convert Layout Builder Javascript tests to NightWatch

Here is that same fix.

Lets see if it works.

tedbow’s picture

Ok I don't think we actually need waitForNoElement().

Also if we are going to use assertSaveLayout() here which should only have a instance of this method so making LayoutBuilderTestBase

Status: Needs review » Needs work

The last submitted patch, 32: interdiff-31-32.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
951 bytes
17.5 KB
  1. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php
    @@ -0,0 +1,96 @@
    +use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
    

    Can remove this

  2. +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php
    @@ -0,0 +1,96 @@
    +    $this->waitForNoElement('#drupal-off-canvas');
    

    Forgot to remove this call.

    Also forgot to test locally, whoops

tim.plunkett’s picture

My hesitation with the above approach is that there is nothing special about saving layouts here. It just happens to be the action we perform after the long-running AJAX request of adding the section and waiting for the rebuilt UI.

The flow of that modification is not essential here, Cancel and Save should work the same.
So here's a patch that sidesteps the random failure by moving the modification to a dedicated (and safer method).

It also clarifies the test a bit better, to show what we actually care about testing, and which part are just necessary set-up.

Here's a (hopefully) committable patch as well as a x30 run version.

Interdiff is against #19.

tedbow’s picture

Status: Needs review » Reviewed & tested by the community

This look like a better solution to be. RTBC. Assuming will pass tests since x30 patch passed.

  • webchick committed ebcf145 on 8.7.x
    Issue #2919795 by tim.plunkett, tedbow, dead_arm, webchick, alexpott,...
webchick’s picture

Status: Reviewed & tested by the community » Fixed

Ok, hopefully second time's a charm ;)

Committed and pushed to 8.7.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

webchick’s picture

Sorry; backported to 8.6.x as well.