diff --git a/core/modules/layout_builder/css/layout-builder.css b/core/modules/layout_builder/css/layout-builder.css index c920f23bd40b..047427440e30 100644 --- a/core/modules/layout_builder/css/layout-builder.css +++ b/core/modules/layout_builder/css/layout-builder.css @@ -85,3 +85,34 @@ display: block; padding-top: 0.55em; } + +#drupal-off-canvas a.inline-block-create-button { + display: block; + padding: 24px; + padding-left: 44px; + font-size: 16px; + color: #EEE; + border-bottom: 1px solid #333; + background: url(../../../misc/icons/bebebe/plus.svg) transparent 16px no-repeat; +} + +#drupal-off-canvas a.inline-block-create-button, +#drupal-off-canvas .inline-block-list a { + margin: 0 -20px; + transition: background-color 0.5s; + background-color: #444; +} + +#drupal-off-canvas a.inline-block-create-button:hover, +#drupal-off-canvas .inline-block-list a:hover { + background-color: #333; +} + +#drupal-off-canvas .inline-block-list { + margin-bottom: 15px; +} + +#drupal-off-canvas .inline-block-list a { + display: block; + padding: 15px 0 15px 25px; +} diff --git a/core/modules/layout_builder/js/layout-builder.es6.js b/core/modules/layout_builder/js/layout-builder.es6.js index f8f7b0be4685..7f3097336743 100644 --- a/core/modules/layout_builder/js/layout-builder.es6.js +++ b/core/modules/layout_builder/js/layout-builder.es6.js @@ -1,5 +1,67 @@ -(($, { ajax, behaviors }) => { - behaviors.layoutBuilder = { +(($, { ajax, behaviors, debounce }) => { + behaviors.layoutBuilderBlockFilter = { + attach(context) { + const $input = $('input.js-layout-builder-filter', context).once('block-filter-text'); + const $categories = $('.js-layout-builder-categories', context); + let $filterLinks; + + /** + * Filters the block list. + * + * @param {jQuery.Event} e + * The jQuery event for the keyup event that triggered the filter. + */ + function filterBlockList(e) { + const query = $(e.target) + .val() + .toLowerCase(); + + /** + * Shows or hides the block entry based on the query. + * + * @param {number} index + * The index in the loop, as provided by `jQuery.each` + * @param {HTMLElement} link + * The link to add the block. + */ + function toggleBlockEntry(index, link) { + const $link = $(link); + const textMatch = + $link + .text() + .toLowerCase() + .indexOf(query) !== -1; + $link.toggle(textMatch); + } + + $categories.find('.js-layout-builder-category').show(); + $filterLinks.show(); + + // Filter if the length of the query is at least 2 characters. + if (query.length >= 2) { + $categories.find('.js-layout-builder-category').attr('open', ''); + $filterLinks.each(toggleBlockEntry); + $categories.find('.js-layout-builder-category').each(function() { + const hasBlocks = $(this).find('.js-layout-builder-block-link:visible').length > 0; + $(this).toggle(hasBlocks); + }); + Drupal.announce( + Drupal.formatPlural( + $categories.find('.js-layout-builder-block-link:visible').length, + '1 block is available in the modified list.', + '@count blocks are available in the modified list.', + ), + ); + } + } + + if ($input.length) { + $filterLinks = $categories.find('.js-layout-builder-block-link'); + $input.on('keyup', debounce(filterBlockList, 200)); + } + } + }; + behaviors.layoutBuilderBlockDrag = { attach(context) { $(context) .find('.layout-builder--layout__region') diff --git a/core/modules/layout_builder/js/layout-builder.js b/core/modules/layout_builder/js/layout-builder.js index 0f0de275ef6d..f0e53fac4a33 100644 --- a/core/modules/layout_builder/js/layout-builder.js +++ b/core/modules/layout_builder/js/layout-builder.js @@ -7,9 +7,45 @@ (function ($, _ref) { var ajax = _ref.ajax, - behaviors = _ref.behaviors; + behaviors = _ref.behaviors, + debounce = _ref.debounce; - behaviors.layoutBuilder = { + behaviors.layoutBuilderBlockFilter = { + attach: function attach(context) { + var $input = $('input.js-layout-builder-filter', context).once('block-filter-text'); + var $categories = $('.js-layout-builder-categories', context); + var $filterLinks = void 0; + + function filterBlockList(e) { + var query = $(e.target).val().toLowerCase(); + + function toggleBlockEntry(index, link) { + var $link = $(link); + var textMatch = $link.text().toLowerCase().indexOf(query) !== -1; + $link.toggle(textMatch); + } + + $categories.find('.js-layout-builder-category').show(); + $filterLinks.show(); + + if (query.length >= 2) { + $categories.find('.js-layout-builder-category').attr('open', ''); + $filterLinks.each(toggleBlockEntry); + $categories.find('.js-layout-builder-category').each(function () { + var hasBlocks = $(this).find('.js-layout-builder-block-link:visible').length > 0; + $(this).toggle(hasBlocks); + }); + Drupal.announce(Drupal.formatPlural($categories.find('.js-layout-builder-block-link:visible').length, '1 block is available in the modified list.', '@count blocks are available in the modified list.')); + } + } + + if ($input.length) { + $filterLinks = $categories.find('.js-layout-builder-block-link'); + $input.on('keyup', debounce(filterBlockList, 200)); + } + } + }; + behaviors.layoutBuilderBlockDrag = { attach: function attach(context) { $(context).find('.layout-builder--layout__region').sortable({ items: '> .draggable', diff --git a/core/modules/layout_builder/layout_builder.libraries.yml b/core/modules/layout_builder/layout_builder.libraries.yml index 84727756365b..cfa1ecf249d6 100644 --- a/core/modules/layout_builder/layout_builder.libraries.yml +++ b/core/modules/layout_builder/layout_builder.libraries.yml @@ -8,3 +8,5 @@ drupal.layout_builder: dependencies: - core/jquery.ui.sortable - core/drupal.dialog.off_canvas + - core/drupal.announce + - core/drupal.debounce diff --git a/core/modules/layout_builder/layout_builder.module b/core/modules/layout_builder/layout_builder.module index 5d7c60615cf0..48f62e98cf19 100644 --- a/core/modules/layout_builder/layout_builder.module +++ b/core/modules/layout_builder/layout_builder.module @@ -177,7 +177,7 @@ function layout_builder_cron() { function layout_builder_plugin_filter_block_alter(array &$definitions, array $extra, $consumer) { // @todo Determine the 'inline_block' blocks should be allowed outside // of layout_builder https://www.drupal.org/node/2979142. - if ($consumer !== 'layout_builder') { + if ($consumer !== 'layout_builder' || !isset($extra['list']) || $extra['list'] !== 'inline_blocks') { foreach ($definitions as $id => $definition) { if ($definition['id'] === 'inline_block') { unset($definitions[$id]); diff --git a/core/modules/layout_builder/layout_builder.routing.yml b/core/modules/layout_builder/layout_builder.routing.yml index 54c9cf25b23a..3e3ee1b0241c 100644 --- a/core/modules/layout_builder/layout_builder.routing.yml +++ b/core/modules/layout_builder/layout_builder.routing.yml @@ -80,6 +80,19 @@ layout_builder.add_block: section_storage: layout_builder_tempstore: TRUE +layout_builder.choose_inline_block: + path: '/layout_builder/choose/inline-block/{section_storage_type}/{section_storage}/{delta}/{region}' + defaults: + _controller: '\Drupal\layout_builder\Controller\ChooseBlockController::inlineBlockList' + _title: 'Add a new Inline Block' + requirements: + _permission: 'configure any layout' + options: + _admin_route: TRUE + parameters: + section_storage: + layout_builder_tempstore: TRUE + layout_builder.update_block: path: '/layout_builder/update/block/{section_storage_type}/{section_storage}/{delta}/{region}/{uuid}' defaults: diff --git a/core/modules/layout_builder/src/Controller/ChooseBlockController.php b/core/modules/layout_builder/src/Controller/ChooseBlockController.php index 4f25eb09bd1b..a737fa466d97 100644 --- a/core/modules/layout_builder/src/Controller/ChooseBlockController.php +++ b/core/modules/layout_builder/src/Controller/ChooseBlockController.php @@ -5,10 +5,13 @@ use Drupal\Core\Ajax\AjaxHelperTrait; use Drupal\Core\Block\BlockManagerInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\layout_builder\Context\LayoutBuilderContextTrait; use Drupal\layout_builder\SectionStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Entity\EntityTypeRepositoryInterface; /** * Defines a controller to choose a new block. @@ -19,6 +22,7 @@ class ChooseBlockController implements ContainerInjectionInterface { use AjaxHelperTrait; use LayoutBuilderContextTrait; + use StringTranslationTrait; /** * The block manager. @@ -27,14 +31,34 @@ class ChooseBlockController implements ContainerInjectionInterface { */ protected $blockManager; + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The entity type repository. + * + * @var \Drupal\Core\Entity\EntityTypeRepositoryInterface + */ + protected $entityTypeRepository; + /** * ChooseBlockController constructor. * * @param \Drupal\Core\Block\BlockManagerInterface $block_manager * The block manager. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + * @param \Drupal\Core\Entity\EntityTypeRepositoryInterface $entity_type_repository + * The entity type repository. */ - public function __construct(BlockManagerInterface $block_manager) { + public function __construct(BlockManagerInterface $block_manager, EntityTypeManagerInterface $entity_type_manager, EntityTypeRepositoryInterface $entity_type_repository) { $this->blockManager = $block_manager; + $this->entityTypeManager = $entity_type_manager; + $this->entityTypeRepository = $entity_type_repository; } /** @@ -42,7 +66,9 @@ public function __construct(BlockManagerInterface $block_manager) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('plugin.manager.block') + $container->get('plugin.manager.block'), + $container->get('entity_type.manager'), + $container->get('entity_type.repository') ); } @@ -60,8 +86,55 @@ public static function create(ContainerInterface $container) { * A render array. */ public function build(SectionStorageInterface $section_storage, $delta, $region) { - $build['#type'] = 'container'; - $build['#attributes']['class'][] = 'block-categories'; + $entity_type_label = $this->getEntityFieldCategoryLabels(); + if ($this->entityTypeManager->hasDefinition('block_content_type') && $types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple()) { + if (count($types) === 1) { + $type = reset($types); + $plugin_id = 'inline_block:' . $type->id(); + if ($this->blockManager->hasDefinition($plugin_id)) { + $url = Url::fromRoute('layout_builder.add_block', [ + 'section_storage_type' => $section_storage->getStorageType(), + 'section_storage' => $section_storage->getStorageId(), + 'delta' => $delta, + 'region' => $region, + 'plugin_id' => $plugin_id, + ]); + } + } + else { + $url = Url::fromRoute('layout_builder.choose_inline_block', [ + 'section_storage_type' => $section_storage->getStorageType(), + 'section_storage' => $section_storage->getStorageId(), + 'delta' => $delta, + 'region' => $region, + ]); + } + if (isset($url)) { + $build['add_block'] = [ + '#type' => 'link', + '#url' => $url, + '#title' => $this->t('Create new content'), + '#attributes' => $this->getAjaxAttributes(), + ]; + $build['add_block']['#attributes']['class'][] = 'inline-block-create-button'; + } + } + + $build['filter'] = [ + '#type' => 'search', + '#title' => $this->t('Filter'), + '#title_display' => 'invisible', + '#size' => 30, + '#placeholder' => $this->t('Filter by block name'), + '#attributes' => [ + 'class' => ['js-layout-builder-filter'], + 'title' => $this->t('Enter a part of the block name to filter by.'), + ], + ]; + + $block_categories['#type'] = 'container'; + $block_categories['#attributes']['class'][] = 'block-categories'; + $block_categories['#attributes']['class'][] = 'js-layout-builder-categories'; // @todo Explicitly cast delta to an integer, remove this in // https://www.drupal.org/project/drupal/issues/2984509. @@ -72,35 +145,171 @@ public function build(SectionStorageInterface $section_storage, $delta, $region) 'delta' => $delta, 'region' => $region, ]); - foreach ($this->blockManager->getGroupedDefinitions($definitions) as $category => $blocks) { - $build[$category]['#type'] = 'details'; - $build[$category]['#open'] = TRUE; - $build[$category]['#title'] = $category; - $build[$category]['links'] = [ - '#theme' => 'links', + $field_block_category_weight = -200; + $non_view_configurable_field_links = []; + $links = []; + $grouped_definitions = $this->blockManager->getGroupedDefinitions($definitions); + foreach ($grouped_definitions as $category => $blocks) { + $block_categories[$category]['#type'] = 'details'; + $block_categories[$category]['#attributes']['class'][] = 'js-layout-builder-category'; + $block_categories[$category]['#open'] = FALSE; + $block_categories[$category]['#title'] = $category; + $this->addBlockLinks($block_categories[$category], $section_storage, $delta, $region, $blocks); + } + $build['block_categories'] = $block_categories; + return $build; + } + + /** + * Provides the UI for choosing a new inline block. + * + * @param \Drupal\layout_builder\SectionStorageInterface $section_storage + * The section storage. + * @param int $delta + * The delta of the section to splice. + * @param string $region + * The region the block is going in. + * + * @return array + * A render array. + */ + public function inlineBlockList(SectionStorageInterface $section_storage, $delta, $region) { + $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [ + 'section_storage' => $section_storage, + 'region' => $region, + 'list' => 'inline_blocks', + ]); + $blocks = $this->blockManager->getGroupedDefinitions($definitions); + $build = []; + if (isset($blocks['Inline blocks'])) { + $this->addBlockLinks($build, $section_storage, $delta, $region, $blocks['Inline blocks']); + $build['links']['#attributes']['class'][] = 'inline-block-list'; + $build['back_button'] = [ + '#type' => 'link', + '#url' => Url::fromRoute('layout_builder.choose_block', + [ + 'section_storage_type' => $section_storage->getStorageType(), + 'section_storage' => $section_storage->getStorageId(), + 'delta' => $delta, + 'region' => $region, + ] + ), + '#title' => $this->t('Back'), + '#attributes' => $this->getAjaxAttributes(), + ]; + } + return $build; + } + + /** + * Adds a render array of block links. + * + * @param array $render_array + * Render array to add links to. + * @param \Drupal\layout_builder\SectionStorageInterface $section_storage + * The section storage. + * @param int $delta + * The delta of the section to splice. + * @param string $region + * The region the block is going in. + * @param array $blocks + * The information for each block. + * + * @return array + * The block links render array. + */ + protected function addBlockLinks(&$render_array, SectionStorageInterface $section_storage, $delta, $region, array $blocks) { + static $field_block_category_weight = -200; + $links = []; + $category = NULL; + foreach ($blocks as $block_id => $block) { + if (!$category) { + $category = $block['category']; + } + $attributes = $this->getAjaxAttributes(); + $attributes['class'][] = 'js-layout-builder-block-link'; + $link = [ + 'title' => $block['admin_label'], + 'url' => Url::fromRoute('layout_builder.add_block', + [ + 'section_storage_type' => $section_storage->getStorageType(), + 'section_storage' => $section_storage->getStorageId(), + 'delta' => $delta, + 'region' => $region, + 'plugin_id' => $block_id, + ] + ), + 'attributes' => $attributes, ]; - foreach ($blocks as $block_id => $block) { - $link = [ - 'title' => $block['admin_label'], - 'url' => Url::fromRoute('layout_builder.add_block', - [ - 'section_storage_type' => $section_storage->getStorageType(), - 'section_storage' => $section_storage->getStorageId(), - 'delta' => $delta, - 'region' => $region, - 'plugin_id' => $block_id, - ] - ), + if ($block['id'] === 'field_block' && empty($block['_is_view_configurable'])) { + $non_view_configurable_field_links[] = $link; + } + else { + $links[] = $link; + } + } + if ($non_view_configurable_field_links) { + if (empty($links)) { + // If no other links exist add these links as top level links for the + // category. + $links = $non_view_configurable_field_links; + } + else { + $render_array['more_fields'] = [ + '#type' => 'details', + '#title' => $this->t('More+'), + '#open' => FALSE, + 'links' => [ + '#theme' => 'links', + '#links' => $non_view_configurable_field_links, + ], + '#weight' => 100, ]; - if ($this->isAjax()) { - $link['attributes']['class'][] = 'use-ajax'; - $link['attributes']['data-dialog-type'][] = 'dialog'; - $link['attributes']['data-dialog-renderer'][] = 'off_canvas'; - } - $build[$category]['links']['#links'][] = $link; } } - return $build; + // If this a entity category and there are links besides non 'view' + // configurable field blocks move the category to the top and open it. + if (in_array($category, $this->getEntityFieldCategoryLabels()) && $links) { + $render_array['#open'] = TRUE; + $render_array['#weight'] = $field_block_category_weight; + $field_block_category_weight += 10; + } + $render_array['links'] = [ + '#theme' => 'links', + '#links' => $links, + ]; + } + + /** + * Get dialog attributes if an ajax request. + * + * @return array + * The attributes array. + */ + protected function getAjaxAttributes() { + if ($this->isAjax()) { + return [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'dialog', + 'data-dialog-renderer' => 'off_canvas', + ]; + } + return []; + } + + /** + * Gets the category labels used for entity fields. + * + * @return string[] + * The category labels. + */ + protected function getEntityFieldCategoryLabels() { + $entity_type_labels = $this->entityTypeRepository->getEntityTypeLabels(); + foreach ($entity_type_labels as &$entity_type_label) { + $entity_type_label = $this->t('@entity fields', ['@entity' => $entity_type_label]) + ->render(); + } + return $entity_type_labels; } } diff --git a/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php b/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php index 57d2c1ec7c45..b7a686a5f082 100644 --- a/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php +++ b/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php @@ -118,6 +118,11 @@ public function getDerivativeDefinitions($base_plugin_definition) { // unavailable to place in the block UI. $derivative['_block_ui_hidden'] = !$field_definition->isDisplayConfigurable('view'); + // Mark as view configurable or not to enable highlighting of view + // configurable fields in the 'Add Block' listing of the layout + // builder. + $derivative['_is_view_configurable'] = $field_definition->isDisplayConfigurable('view'); + $context_definition = EntityContextDefinition::fromEntityTypeId($entity_type_id)->setLabel($entity_type_labels[$entity_type_id]); $context_definition->addConstraint('Bundle', [$bundle]); $derivative['context'] = [ diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php index 653185fe8964..0b9cd701ead6 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php @@ -2,14 +2,12 @@ namespace Drupal\Tests\layout_builder\FunctionalJavascript; -use Drupal\FunctionalJavascriptTests\WebDriverTestBase; - /** * Ajax blocks tests. * * @group layout_builder */ -class AjaxBlockTest extends WebDriverTestBase { +class AjaxBlockTest extends LayoutBuilderTestBase { /** * {@inheritdoc} @@ -71,7 +69,8 @@ public function testAddAjaxBlock() { $assert_session->linkExists('Add Block'); $this->clickLink('Add Block'); $assert_session->assertWaitOnAjaxRequest(); - $assert_session->linkExists('TestAjax'); + $this->clickBlockCategory('Test'); + $this->assertBlockLinkVisible('TestAjax'); $this->clickLink('TestAjax'); $assert_session->assertWaitOnAjaxRequest(); // Find the radio buttons. diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php index 05892bd31473..481247e0b638 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php @@ -192,8 +192,8 @@ protected function addInlineFileBlockToLayout($title, File $file) { $page = $this->getSession()->getPage(); $page->clickLink('Add Block'); $assert_session->assertWaitOnAjaxRequest(); - $this->assertNotEmpty($assert_session->waitForElementVisible('css', '.block-categories details:contains(Create new block)')); - $this->clickLink('Basic block'); + $this->assertNotEmpty($assert_session->waitForLink('Create new content')); + $this->clickLink('Create new content'); $assert_session->assertWaitOnAjaxRequest(); $assert_session->fieldValueEquals('Title', ''); $page->findField('Title')->setValue($title); diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php index 9fdc8fdd3cca..270e88b9bbfb 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php @@ -428,4 +428,73 @@ public function testAccess() { $assert_session->pageTextNotContains('You are not authorized to access this page'); } + /** + * Tests the workflow for adding an inline block depending on number of types. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * @throws \Behat\Mink\Exception\ExpectationException + */ + public function testAddWorkFlow() { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + $type_storage = $this->container->get('entity_type.manager')->getStorage('block_content_type'); + foreach ($type_storage->loadByProperties() as $type) { + $type->delete(); + } + + $this->drupalLogin($this->drupalCreateUser([ + 'access contextual links', + 'configure any layout', + 'administer node display', + 'administer node fields', + ])); + + // Enable layout builder and overrides. + $this->drupalPostForm( + static::FIELD_UI_PREFIX . '/display/default', + ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], + 'Save' + ); + + $layout_default_path = 'admin/structure/types/manage/bundle_with_section_field/display-layout/default'; + $this->drupalGet($layout_default_path); + // Add a basic block with the body field set. + $page->clickLink('Add Block'); + $assert_session->assertWaitOnAjaxRequest(); + // Confirm that with no block content types the link does not appear. + $assert_session->linkNotExists('Create new content'); + + $this->createBlockContentType('basic', 'Basic block'); + + $this->drupalGet($layout_default_path); + // Add a basic block with the body field set. + $page->clickLink('Add Block'); + $assert_session->assertWaitOnAjaxRequest(); + // Confirm with only 1 type the "Create new content" link goes directly to block + // add form. + $assert_session->linkNotExists('Basic block'); + $this->clickLink('Create new content'); + $assert_session->assertWaitOnAjaxRequest(); + $assert_session->fieldExists('Title'); + + $this->createBlockContentType('advanced', 'Advanced block'); + + $this->drupalGet($layout_default_path); + // Add a basic block with the body field set. + $page->clickLink('Add Block'); + // Confirm more than 1 type exists "Create new content" shows a list block types. + $assert_session->assertWaitOnAjaxRequest(); + $assert_session->linkNotExists('Basic block'); + $assert_session->linkNotExists('Advanced block'); + $this->clickLink('Create new content'); + $assert_session->assertWaitOnAjaxRequest(); + $assert_session->fieldNotExists('Title'); + $assert_session->linkExists('Basic block'); + $assert_session->linkExists('Advanced block'); + + $this->clickLink('Advanced block'); + $assert_session->assertWaitOnAjaxRequest(); + $assert_session->fieldExists('Title'); + } + } diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTestBase.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTestBase.php index 6c99c6c39f10..4bd24d754c88 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTestBase.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTestBase.php @@ -3,13 +3,12 @@ namespace Drupal\Tests\layout_builder\FunctionalJavascript; use Drupal\block_content\Entity\BlockContentType; -use Drupal\FunctionalJavascriptTests\WebDriverTestBase; use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait; /** * Base class for testing inline blocks. */ -abstract class InlineBlockTestBase extends WebDriverTestBase { +abstract class InlineBlockTestBase extends LayoutBuilderTestBase { use ContextualLinkClickTrait; @@ -71,13 +70,7 @@ protected function setUp() { ], ], ]); - $bundle = BlockContentType::create([ - 'id' => 'basic', - 'label' => 'Basic block', - 'revision' => 1, - ]); - $bundle->save(); - block_content_add_body_field($bundle->id()); + $this->createBlockContentType('basic', 'Basic block'); $this->blockStorage = $this->container->get('entity_type.manager')->getStorage('block_content'); } @@ -146,8 +139,8 @@ protected function addInlineBlockToLayout($title, $body) { $page = $this->getSession()->getPage(); $page->clickLink('Add Block'); $assert_session->assertWaitOnAjaxRequest(); - $this->assertNotEmpty($assert_session->waitForElementVisible('css', '.block-categories details:contains(Create new block)')); - $this->clickLink('Basic block'); + $this->assertNotEmpty($assert_session->waitForLink('Create new content')); + $this->clickLink('Create new content'); $assert_session->assertWaitOnAjaxRequest(); $textarea = $assert_session->waitForElement('css', '[name="settings[block_form][body][0][value]"]'); $this->assertNotEmpty($textarea); @@ -219,4 +212,22 @@ protected function assertDialogClosedAndTextVisible($text, $css_locator = NULL) } } + /** + * Creates a block content type. + * + * @param string $id + * The block type id. + * @param string $label + * The block type label. + */ + protected function createBlockContentType($id, $label) { + $bundle = BlockContentType::create([ + 'id' => $id, + 'label' => $label, + 'revision' => 1, + ]); + $bundle->save(); + block_content_add_body_field($bundle->id()); + } + }