diff --git a/core/modules/media_library/config/install/views.view.media_library.yml b/core/modules/media_library/config/install/views.view.media_library.yml index a4f2190892..2f885f627d 100644 --- a/core/modules/media_library/config/install/views.view.media_library.yml +++ b/core/modules/media_library/config/install/views.view.media_library.yml @@ -535,6 +535,7 @@ display: filter_groups: false arguments: false header: false + css_class: false display_description: '' access: type: perm @@ -682,6 +683,7 @@ display: label: 'Show as table' plugin_id: display_link empty: true + css_class: 'media-library-view js-media-library-view media-library-view--widget' cache_metadata: max-age: -1 contexts: @@ -713,6 +715,7 @@ display: filter_groups: false arguments: false header: false + css_class: false row: type: fields fields: @@ -923,6 +926,7 @@ display: label: 'Show as table' plugin_id: display_link empty: true + css_class: 'media-library-view js-media-library-view media-library-view--widget' cache_metadata: max-age: -1 contexts: diff --git a/core/modules/media_library/css/media_library.module.css b/core/modules/media_library/css/media_library.module.css index eafee6e787..d5b69262c2 100644 --- a/core/modules/media_library/css/media_library.module.css +++ b/core/modules/media_library/css/media_library.module.css @@ -67,8 +67,7 @@ width: 100%; } -.media-library-view.view-display-id-widget .media-library-select-all, -.media-library-view.view-display-id-widget_table .media-library-select-all { +.media-library-view--widget .media-library-select-all { display: none; } @@ -82,7 +81,7 @@ /* @todo Remove or re-work in https://www.drupal.org/node/2985168 */ .media-library-widget .media-library-item__name a, -.media-library-view.view-display-id-widget .media-library-item__name a { +.media-library-view--widget .media-library-item__name a { pointer-events: none; } diff --git a/core/modules/media_library/css/media_library.theme.css b/core/modules/media_library/css/media_library.theme.css index 3e037ed2f4..cb3833ad50 100644 --- a/core/modules/media_library/css/media_library.theme.css +++ b/core/modules/media_library/css/media_library.theme.css @@ -101,10 +101,6 @@ } /* Generic media library view styles. */ -.media-library-view { - min-height: 300px; -} - .media-library-view .form-actions { margin: 0.75em 0; } @@ -412,7 +408,7 @@ /* @todo Remove or re-work in https://www.drupal.org/node/2985168 */ .media-library-widget .media-library-item__name a, -.media-library-view.view-display-id-widget .media-library-item__name a { +.media-library-view--widget .media-library-item__name a { text-decoration: none; color: black; } diff --git a/core/modules/media_library/media_library.module b/core/modules/media_library/media_library.module index 4e83c434df..e920580f9d 100644 --- a/core/modules/media_library/media_library.module +++ b/core/modules/media_library/media_library.module @@ -65,8 +65,14 @@ function media_library_theme() { * Implements hook_preprocess_container(). */ function media_library_preprocess_container(&$variables) { - if (isset($variables['element']['#view_id']) && $variables['element']['#view_id'] === 'media_library' && in_array($variables['element']['#display_id'], ['widget', 'widget_table'])) { + // We need to set an ID on the views element container for the widget displays + // of the media library view, to allow the display links in the header area to + // load via AJAX. + // @see Drupal.behaviors.MediaLibraryViewsDisplay + // @see \Drupal\views\Element\View::preRenderViewElement() + if (isset($variables['element']['#view_id']) && $variables['element']['#view_id'] === 'media_library' && strpos($variables['element']['#display_id'], 'widget') === 0) { $variables['attributes']['id'] = 'media-library-view'; + $variables['attributes']['aria-live'] = 'polite'; } } @@ -76,9 +82,10 @@ function media_library_preprocess_container(&$variables) { function media_library_link_alter(&$variables) { $options = &$variables['options']; // The only way to find the display links is through the options set on the - // link. + // link in DisplayLink::render(). + // @see \Drupal\views\Plugin\views\area\DisplayLink::render() $is_view_display_link = isset($options['view'], $options['target_display_id']); - if ($is_view_display_link && $options['view']->id() === 'media_library' && in_array($options['view']->current_display, ['widget', 'widget_table'])) { + if ($is_view_display_link && $options['view']->id() === 'media_library' && strpos($options['view']->current_display, 'widget') === 0) { $options['attributes']['class'][] = 'js-media-library-view-display-link'; } } @@ -151,7 +158,7 @@ function media_library_form_alter(array &$form, FormStateInterface $form_state, } // Add after build to fix media library views exposed filter's submit button. - if ($form_id === 'views_exposed_form' && strpos('views-exposed-form-media-library-widget', $form['#id']) === 0) { + if ($form_id === 'views_exposed_form' && strpos($form['#id'], 'views-exposed-form-media-library-widget') === 0) { $form['#after_build'][] = '_media_library_views_form_media_library_after_build'; } diff --git a/core/modules/media_library/media_library.post_update.php b/core/modules/media_library/media_library.post_update.php index 4a01c20e3f..9b22436caf 100644 --- a/core/modules/media_library/media_library.post_update.php +++ b/core/modules/media_library/media_library.post_update.php @@ -36,12 +36,21 @@ function media_library_post_update_display_modes() { function media_library_post_update_table_display() { $view = Views::getView('media_library'); + if (!$view) { + return t('The media_library view could not be updated because it has been deleted. The media library module needs this view to display correctly. Uninstall and reinstall the module so the view will be re-created.'); + } + $view->setDisplay('widget'); $grid_display = $view->getDisplay('widget'); + // Override CSS classes to allow targeting widget displays. + $grid_display->overrideOption('css_class', 'media-library-view js-media-library-view media-library-view--widget'); $table_display = $view->newDisplay('page', 'Widget (table)', 'widget_table'); $table_display->setOption('path', 'admin/content/media-widget-table'); + // Override CSS classes to allow targeting widget displays. + $table_display->overrideOption('css_class', 'media-library-view js-media-library-view media-library-view--widget'); + // Set table as the display style. $table_display->overrideOption('style', [ 'type' => 'table', diff --git a/core/modules/media_library/src/MediaLibraryUiBuilder.php b/core/modules/media_library/src/MediaLibraryUiBuilder.php index 1872589a21..1ebb7aa535 100644 --- a/core/modules/media_library/src/MediaLibraryUiBuilder.php +++ b/core/modules/media_library/src/MediaLibraryUiBuilder.php @@ -117,6 +117,9 @@ public function buildUi(MediaLibraryState $state = NULL) { ], 'menu' => $this->buildMediaTypeMenu($state), 'content' => $this->buildLibraryContent($state), + // Attach the javascript for the media library UI. The number of + // available slots needs to be added to make sure users can't select + // more items than allowed. '#attached' => [ 'library' => ['media_library/ui'], 'drupalSettings' => [ diff --git a/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateViewTableDisplayTest.php b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateViewTableDisplayTest.php index c7960e2abe..2c693d1f8c 100644 --- a/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateViewTableDisplayTest.php +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateViewTableDisplayTest.php @@ -25,25 +25,37 @@ protected function setDatabaseDumpFiles() { } /** - * Tests that the media library view config is updated with the table display. + * Tests the widget_table display is added to the views config. * * @see media_library_post_update_table_display() */ public function testMediaLibraryViewTableDisplay() { $config = $this->config('views.view.media_library'); + $this->assertNull($config->get('display.widget.display_options.defaults.css_class')); + $this->assertNull($config->get('display.widget.display_options.css_class')); $this->assertNull($config->get('display.widget_table')); $this->runUpdates(); $config = $this->config('views.view.media_library'); + // Assert the CSS classes are updated for the widget display. + $this->assertFalse($config->get('display.widget.display_options.defaults.css_class')); + $this->assertSame('media-library-view js-media-library-view media-library-view--widget', $config->get('display.widget.display_options.css_class')); + // Assert the widget_table display was added correctly. $this->assertSame('table', $config->get('display.widget_table.display_options.style.type')); $this->assertSame('fields', $config->get('display.widget_table.display_options.row.type')); $this->assertSame(['media_library_select_form', 'thumbnail__target_id', 'name', 'uid', 'changed'], array_keys($config->get('display.widget_table.display_options.fields'))); + // Assert the CSS classes are added to the widget_table display. + $this->assertFalse($config->get('display.widget_table.display_options.defaults.css_class')); + $this->assertSame('media-library-view js-media-library-view media-library-view--widget', $config->get('display.widget_table.display_options.css_class')); + // Assert all display options are set correctly on the widget_table display. $this->assertSame($config->get('display.widget.display_options.filters'), $config->get('display.widget_table.display_options.filters')); $this->assertSame($config->get('display.widget.display_options.access'), $config->get('display.widget_table.display_options.access')); $this->assertSame($config->get('display.widget.display_options.sorts'), $config->get('display.widget_table.display_options.sorts')); $this->assertSame($config->get('display.widget.display_options.pager'), $config->get('display.widget_table.display_options.pager')); $this->assertSame($config->get('display.widget.display_options.arguments'), $config->get('display.widget_table.display_options.arguments')); + // Assert the display links are added to the widget and widget_table + // displays. $this->assertSame('display_link', $config->get('display.widget.display_options.header.display_link_grid.plugin_id')); $this->assertSame('display_link', $config->get('display.widget.display_options.header.display_link_table.plugin_id')); $this->assertSame('display_link', $config->get('display.widget_table.display_options.header.display_link_grid.plugin_id')); @@ -55,13 +67,17 @@ public function testMediaLibraryViewTableDisplay() { } /** - * Tests that the table display when the grid display has been changed. + * Tests the views config update when the widget display is overridden. * * @see media_library_post_update_table_display() */ public function testMediaLibraryChangedViewTableDisplay() { $view = Views::getView('media_library'); + // The existing 'widget' display could have been overridden. The 'widget' + // and 'widget_table' displays need to have the same display options, so we + // need to verify the overridden settings are correctly set when creating + // the 'widget_table' display. $view->setDisplay('widget'); $grid_display = $view->getDisplay('widget'); @@ -94,14 +110,24 @@ public function testMediaLibraryChangedViewTableDisplay() { $this->runUpdates(); $config = $this->config('views.view.media_library'); + // Assert the CSS classes are updated for the widget display. + $this->assertFalse($config->get('display.widget.display_options.defaults.css_class')); + $this->assertSame('media-library-view js-media-library-view media-library-view--widget', $config->get('display.widget.display_options.css_class')); + // Assert the widget_table display was added correctly. $this->assertSame('table', $config->get('display.widget_table.display_options.style.type')); $this->assertSame('fields', $config->get('display.widget_table.display_options.row.type')); $this->assertSame(['media_library_select_form', 'thumbnail__target_id', 'name', 'uid', 'changed'], array_keys($config->get('display.widget_table.display_options.fields'))); + // Assert the CSS classes are added to the widget_table display. + $this->assertFalse($config->get('display.widget_table.display_options.defaults.css_class')); + $this->assertSame('media-library-view js-media-library-view media-library-view--widget', $config->get('display.widget_table.display_options.css_class')); + // Assert all display options are set correctly on the widget_table display. $this->assertSame($config->get('display.widget.display_options.filters'), $config->get('display.widget_table.display_options.filters')); $this->assertSame($config->get('display.widget.display_options.access'), $config->get('display.widget_table.display_options.access')); $this->assertSame($config->get('display.widget.display_options.sorts'), $config->get('display.widget_table.display_options.sorts')); $this->assertSame($config->get('display.widget.display_options.pager'), $config->get('display.widget_table.display_options.pager')); $this->assertSame($config->get('display.widget.display_options.arguments'), $config->get('display.widget_table.display_options.arguments')); + // Assert the display links are added to the widget and widget_table + // displays. $this->assertSame('display_link', $config->get('display.widget.display_options.header.display_link_grid.plugin_id')); $this->assertSame('display_link', $config->get('display.widget.display_options.header.display_link_table.plugin_id')); $this->assertSame('display_link', $config->get('display.widget_table.display_options.header.display_link_grid.plugin_id')); diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php index 9c4fdd2293..533193e97c 100644 --- a/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php +++ b/core/modules/media_library/tests/src/FunctionalJavascript/MediaLibraryTest.php @@ -285,9 +285,14 @@ public function testWidget() { $assert_session->assertWaitOnAjaxRequest(); $assert_session->elementExists('css', '.media-library-view .media-library-item article'); $assert_session->elementNotExists('css', '.media-library-view table tr.media-library-item-table'); + $button_pane = $assert_session->elementExists('css', '.ui-dialog-buttonpane'); + $assert_session->buttonExists('Select media', $button_pane); + $assert_session->buttonNotExists('Apply filters', $button_pane); $assert_session->elementExists('named', ['link', 'Show as grid']); $assert_session->elementExists('named', ['link', 'Show as table'])->click(); $assert_session->assertWaitOnAjaxRequest(); + $assert_session->buttonExists('Select media', $button_pane); + $assert_session->buttonNotExists('Apply filters', $button_pane); $assert_session->pageTextContains('Dog'); $assert_session->pageTextContains('Bear'); $assert_session->pageTextNotContains('Turtle');