diff --git a/admin/tool/componentlibrary/content/moodle/components/actionmenu.md b/admin/tool/componentlibrary/content/moodle/components/actionmenu.md index b9102221131..c8b6aa972e0 100644 --- a/admin/tool/componentlibrary/content/moodle/components/actionmenu.md +++ b/admin/tool/componentlibrary/content/moodle/components/actionmenu.md @@ -39,7 +39,7 @@ The component output classes can render an action menu entirely in PHP. The step The following code is a basic example of an action menu: -{{< php >}} +```php /** @var core_renderer $output*/ $output = $PAGE->get_renderer('core'); @@ -54,11 +54,11 @@ $menu->add(new action_menu_link( )); echo $output->render($menu); -{{< / php >}} +``` And this is the same example but passing the items in the creation: -{{< php >}} +```php /** @var core_renderer $output*/ $output = $PAGE->get_renderer('core'); @@ -72,32 +72,64 @@ $menu = new action_menu([ ]); echo $output->render($menu); -{{< / php >}} +``` ### Setup the menu trigger -By default, the action menu trigger is a cog icon. However, the class has methods to convert it to a kebab menu or even display any arbitrary content. +By default, the action menu trigger is a button that uses the `t/edit_menu` icon and is displayed with a caret. However, the class has methods to convert it to a kebab menu or even display any arbitrary content. -Example of a kebab menu: +#### Example of a kebab menu -{{< php >}} +```php /** @var core_renderer $output*/ $output = $PAGE->get_renderer('core'); $menu = new action_menu(); $menu->set_kebab_trigger(get_string('edit'), $output); $menu->set_additional_classes('fields-actions'); -{{< / php >}} +``` -Example of a custom trigger: +#### Customising the menu trigger -{{< php >}} -/** @var core_renderer $output*/ -$output = $PAGE->get_renderer('core'); +##### Trigger with a text label +```php +// This example displays an "Edit" label for the trigger. $menu = new action_menu(); $menu->set_menu_trigger(get_string('edit')); -{{< / php >}} +``` + +##### Trigger with an icon + +This example displays an icon for the trigger. When rendering the menu trigger button as an icon button, ensure that the icon is rendered as a decorative image. If you are using a `pix_icon`, pass an empty `$alt` parameter to make the icon decorative. + +The accessible name of the icon button should be set within the button element itself. You can set an accessible name for the icon trigger button either by: +* Using the `::set_action_label()` method. +```php +$menu = new action_menu(); +// Make sure the pix icon is rendered as a decorative image by passing an empty alt parameter. +$icon = $output->pix_icon('t/edit', ''); +$menu->set_menu_trigger($icon); +$menu->set_action_label(get_string('edit')); +``` + +* Or alternatively, by adding a visually hidden text alongside the icon. +```php +$menu = new action_menu(); +// Make sure the pix icon is rendered as a decorative image by passing an empty alt parameter. +$icon = $output->pix_icon('t/edit', ''); +// Add a visually hidden text label for the trigger button. +$icon .= html_writer::span(get_string('edit'), 'sr-only'); +$menu->set_menu_trigger($icon); +``` + +##### Removing the caret symbol + +You may also remove the caret symbol by adding a `no-caret` class to the `triggerextraclasses` property. + +```php +$menu->triggerextraclasses = 'no-caret'; +``` ### Add items @@ -108,7 +140,7 @@ Secondary items: are displayed inside the action menu dropdown. The item location must be configured before adding the element. The following example shows different ways to add primary and secondary menu items. -{{< php >}} +```php // Primary items examples. $menu->add(new action_menu_link( new moodle_url($PAGE->url), @@ -134,7 +166,7 @@ $menu->add(new action_menu_link_secondary( new pix_icon('t/user', ''), 'Action link example', )); -{{< / php >}} +``` ## Types of items @@ -178,7 +210,7 @@ Construct params: The following example creates a subpanel using a renderable choicelist instance: -{{< php >}} +```php /** @var core_renderer $output*/ $output = $PAGE->get_renderer('core'); @@ -205,7 +237,7 @@ $menu->add(new core\output\local\action_menu\subpanel( )); echo $output->render($menu); -{{< / php >}} +``` ### HTML string diff --git a/admin/tool/componentlibrary/examples/actionmenu.php b/admin/tool/componentlibrary/examples/actionmenu.php index 0721fb41e81..9b8ce89cfc5 100644 --- a/admin/tool/componentlibrary/examples/actionmenu.php +++ b/admin/tool/componentlibrary/examples/actionmenu.php @@ -77,7 +77,7 @@ echo '

Important note: actions menus are not prepared to be displayed inside iframes. You may need to scroll to see the action menu options.

'; -echo $output->heading("Action menu default example", 4); +echo $output->heading("Action menu default example", 3); $menu = new action_menu(); @@ -87,11 +87,11 @@ $menu->add($subpanel); $menu->add($basicactionlink); echo '
'; -echo '
Example of default an action menu
'; +echo '
An action menu rendered without customisation
'; echo $OUTPUT->render($menu); echo '
'; -echo $output->heading("Kebab menu example", 4); +echo $output->heading("Kebab menu example", 3); $menu = new action_menu(); $menu->set_kebab_trigger(get_string('edit'), $output); @@ -106,11 +106,11 @@ $menu->add(new core\output\local\action_menu\subpanel( $menu->add($basicactionlink); echo '
'; -echo '
Example of kebab menu
'; +echo '
An action menu with a kebab menu trigger button
'; echo $OUTPUT->render($menu); echo '
'; -echo $output->heading("Custom trigger menu example", 4); +echo $output->heading("Custom trigger menu examples", 3); $menu = new action_menu(); $menu->set_menu_trigger(get_string('edit')); @@ -124,11 +124,53 @@ $menu->add(new core\output\local\action_menu\subpanel( $menu->add($basicactionlink); echo '
'; -echo '
Example of kebab menu
'; +echo '
An action menu with a menu trigger button with a custom text label
'; echo $OUTPUT->render($menu); echo '
'; -echo $output->heading("Primary actions menu example", 4); +$links = [ + $basicactionlink, + $basicactionlink, +]; +$moreicon = $OUTPUT->pix_icon('i/moremenu', ''); +$editicon = $OUTPUT->pix_icon('t/edit', ''); + +$menu = new action_menu($links); + +$menu->set_menu_trigger($moreicon); +$menu->set_action_label(get_string('moremenu')); +$menu->triggerattributes = [ + 'title' => get_string('moremenu'), +]; + +echo '
'; +echo '
An action menu with only an icon for its custom menu trigger button
'; +echo html_writer::div($OUTPUT->render($menu)); +echo '
'; + +echo '
'; +echo '
An action menu with only an icon for its custom menu trigger button with the caret removed
'; +$menu->triggerextraclasses = 'no-caret'; +echo html_writer::div($OUTPUT->render($menu)); +echo '
'; + +$menu = new action_menu($links); +$menu->set_menu_trigger($editicon . ' ' . get_string('edit')); + +echo '
'; +echo '
An action menu with an icon and visible text for its custom menu trigger button
'; +echo html_writer::div($OUTPUT->render($menu)); +echo '
'; + +$menu = new action_menu($links); +$menu->set_menu_trigger($editicon . ' ' . html_writer::span(get_string('edit'), 'sr-only')); + +echo '
'; +echo '
An action menu with an icon and visually hidden text for its custom menu trigger button
'; +echo html_writer::div($OUTPUT->render($menu)); +echo '
'; + +echo $output->heading("Primary actions menu example", 3); $menu = new action_menu(); $menu->set_menu_trigger(get_string('edit')); diff --git a/blocks/accessreview/tests/accessreview.feature b/blocks/accessreview/tests/accessreview.feature index 8f1f2371ed8..4adc163c0df 100644 --- a/blocks/accessreview/tests/accessreview.feature +++ b/blocks/accessreview/tests/accessreview.feature @@ -22,9 +22,9 @@ Feature: Block accessreview When I add the "Accessibility Review" block Then I should see "Accessibility Review" And I should see "Your accessibility toolkit needs to be registered." - And I click on "Actions menu" "icon" in the "Accessibility Review" "block" + And I click on "Actions menu" "menuitem" in the "Accessibility Review" "block" And I follow "Hide Accessibility Review block" And I should not see "Your accessibility toolkit needs to be registered." - And I click on "Actions menu" "icon" in the "Accessibility Review" "block" + And I click on "Actions menu" "menuitem" in the "Accessibility Review" "block" And I follow "Show Accessibility Review block" And I should see "Your accessibility toolkit needs to be registered." diff --git a/blocks/accessreview/tests/behat/accessreview.feature b/blocks/accessreview/tests/behat/accessreview.feature index c56a5ec178d..090620e0f85 100644 --- a/blocks/accessreview/tests/behat/accessreview.feature +++ b/blocks/accessreview/tests/behat/accessreview.feature @@ -24,9 +24,9 @@ Feature: Block accessreview When I add the "Accessibility review" block Then I should see "Accessibility review" And I should see "Your accessibility toolkit needs to be registered." - And I click on "Actions menu" "icon" in the "Accessibility review" "block" + And I click on "Actions menu" "menuitem" in the "Accessibility review" "block" And I follow "Hide Accessibility review block" And I should not see "Your accessibility toolkit needs to be registered." - And I click on "Actions menu" "icon" in the "Accessibility review" "block" + And I click on "Actions menu" "menuitem" in the "Accessibility review" "block" And I follow "Show Accessibility review block" And I should see "Your accessibility toolkit needs to be registered." diff --git a/course/classes/management_renderer.php b/course/classes/management_renderer.php index 2a3da7408d2..77d62540fa0 100644 --- a/course/classes/management_renderer.php +++ b/course/classes/management_renderer.php @@ -343,6 +343,10 @@ class core_course_management_renderer extends plugin_renderer_base { $actions = \core_course\management\helper::get_category_listitem_actions($category); } $menu = new action_menu(); + $label = get_string('actionsmenu'); + $actionicon = $this->output->pix_icon('t/edit_menu', '') . html_writer::span($label, 'sr-only'); + $menu->set_menu_trigger($actionicon, 'iconsmall actionmenu'); + $menu->triggerattributes['title'] = $label; $menu->attributes['class'] .= ' category-item-actions item-actions'; $hasitems = false; foreach ($actions as $key => $action) { diff --git a/grade/lib.php b/grade/lib.php index 34d9b448f98..e927b0aab35 100644 --- a/grade/lib.php +++ b/grade/lib.php @@ -1620,9 +1620,11 @@ class grade_structure { if ($menuitems) { $menu = new action_menu($menuitems); - $icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions')); + $label = get_string('actions'); + $icon = $OUTPUT->pix_icon('i/moremenu', '') . \core\output\html_writer::span($label, 'sr-only d-inline-block'); $extraclasses = 'btn btn-link btn-icon icon-size-3 d-flex align-items-center justify-content-center no-caret'; $menu->set_menu_trigger($icon, $extraclasses); + $menu->triggerattributes['title'] = $label; $menu->set_menu_left(); return $OUTPUT->render($menu); diff --git a/grade/report/singleview/classes/local/screen/grade.php b/grade/report/singleview/classes/local/screen/grade.php index 376b7ab1183..7c1030917c6 100644 --- a/grade/report/singleview/classes/local/screen/grade.php +++ b/grade/report/singleview/classes/local/screen/grade.php @@ -423,9 +423,11 @@ class grade extends tablelike implements selectable_items, filterable_items { $title = get_string('showallgrades', 'core_grades'); $menuitems[] = new \action_menu_link_secondary($url, null, $title); $menu = new \action_menu($menuitems); - $icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions')); + $label = get_string('actions'); + $icon = $OUTPUT->pix_icon('i/moremenu', '') . \core\output\html_writer::span($label, 'sr-only d-inline-block'); $extraclasses = 'btn btn-link btn-icon icon-size-3 d-flex align-items-center justify-content-center'; $menu->set_menu_trigger($icon, $extraclasses); + $menu->triggerattributes['title'] = $label; $menu->set_menu_left(); $menu->set_boundary('window'); diff --git a/grade/report/singleview/classes/local/screen/user.php b/grade/report/singleview/classes/local/screen/user.php index bc3b6c998ab..48259f64018 100644 --- a/grade/report/singleview/classes/local/screen/user.php +++ b/grade/report/singleview/classes/local/screen/user.php @@ -268,9 +268,11 @@ class user extends tablelike implements selectable_items { $title = get_string('showallgrades', 'core_grades'); $menuitems[] = new \action_menu_link_secondary($url, null, $title); $menu = new \action_menu($menuitems); - $icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions')); + $label = get_string('actions'); + $icon = $OUTPUT->pix_icon('i/moremenu', '') . \core\output\html_writer::span($label, 'sr-only d-inline-block'); $extraclasses = 'btn btn-link btn-icon icon-size-3 d-flex align-items-center justify-content-center'; $menu->set_menu_trigger($icon, $extraclasses); + $menu->triggerattributes['title'] = $label; $menu->set_menu_left(); $menu->set_boundary('window'); diff --git a/lib/behat/classes/partial_named_selector.php b/lib/behat/classes/partial_named_selector.php index 60529a30abb..6363d443bcd 100644 --- a/lib/behat/classes/partial_named_selector.php +++ b/lib/behat/classes/partial_named_selector.php @@ -154,7 +154,7 @@ XPATH descendant::*[ contains(concat(' ', normalize-space(@class), ' '), ' dropdown-toggle ') and - (contains(normalize-space(.), %locator%) or descendant::*[%titleMatch%]) + (contains(normalize-space(.), %locator%) or descendant::*[%titleMatch%] or %ariaLabelMatch%) ] ] XPATH diff --git a/lib/classes/output/action_menu.php b/lib/classes/output/action_menu.php index 261054f1f96..d5dcc7d547d 100644 --- a/lib/classes/output/action_menu.php +++ b/lib/classes/output/action_menu.php @@ -218,7 +218,8 @@ class action_menu implements renderable, templatable { } $label = $triggername ?? get_string('actions'); $triggerclasses = self::DEFAULT_KEBAB_TRIGGER_CLASSES . ' ' . $extraclasses; - $icon = $output->pix_icon('i/menu', $label); + $icon = $output->pix_icon('i/menu', '') . html_writer::span($label, 'sr-only'); + $this->triggerattributes += ['title' => $label]; $this->set_menu_trigger($icon, $triggerclasses); } diff --git a/lib/templates/action_menu_trigger.mustache b/lib/templates/action_menu_trigger.mustache index fbe27c74f5a..f4cedb789ee 100644 --- a/lib/templates/action_menu_trigger.mustache +++ b/lib/templates/action_menu_trigger.mustache @@ -88,7 +88,7 @@ tabindex="0" class="{{triggerextraclasses}} dropdown-toggle icon-no-margin" id="action-menu-toggle-{{instance}}" - aria-label="{{title}}" + {{#title}}aria-label="{{title}}"{{/title}} data-toggle="dropdown" role="{{triggerrole}}" aria-haspopup="true" @@ -102,7 +102,7 @@ {{{menutrigger}}} {{#icon}} {{#pix}} - {{key}},{{component}},{{title}} + {{key}},{{component}} {{/pix}} {{/icon}} {{#rawicon}}{{{.}}}{{/rawicon}} diff --git a/mod/data/preset/imagegallery/tests/behat/imagegallery_preset.feature b/mod/data/preset/imagegallery/tests/behat/imagegallery_preset.feature index c5d0816fad3..471d7013f10 100644 --- a/mod/data/preset/imagegallery/tests/behat/imagegallery_preset.feature +++ b/mod/data/preset/imagegallery/tests/behat/imagegallery_preset.feature @@ -36,7 +36,7 @@ Feature: Users can use the Image gallery preset And I should not see "first.png" And I should not see "Alice Student" in the "#imagegallery-list" "css_element" And "//a/child::img[contains(@src, 'first.png')]" "xpath_element" should exist - And "Actions" "icon" should exist in the "#imagegallery-list" "css_element" + And "Actions" "button" should exist in the "#imagegallery-list" "css_element" And I should see "Second image" And I should not see "And this is the description text for image 2" And I should not see "second.png" @@ -48,7 +48,7 @@ Feature: Users can use the Image gallery preset And I should see "Alice Student" in the ".imagegallery-single" "css_element" And I should see "This is the description text for image 1" And "//a/child::img[contains(@src, 'first.png')]" "xpath_element" should exist - And "Actions" "icon" should exist in the ".imagegallery-single" "css_element" + And "Actions" "button" should exist in the ".imagegallery-single" "css_element" And I should not see "Second image" And I should not see "And this is the description text for image 2" And I should not see "Pau Teacher" @@ -59,7 +59,7 @@ Feature: Users can use the Image gallery preset And I should see "And this is the description text for image 2" And "//a/child::img[contains(@src, 'second.png')]" "xpath_element" should exist # This student can't edit or delete this entry, so the Actions menu shouldn't be displayed. - And "Actions" "icon" should not exist in the ".imagegallery-single" "css_element" + And "Actions" "button" should not exist in the ".imagegallery-single" "css_element" And I should not see "First image" And I should not see "Alice Student" in the ".imagegallery-single" "css_element" And I should not see "This is the description text for image 1" diff --git a/mod/data/preset/journal/tests/behat/journal_preset.feature b/mod/data/preset/journal/tests/behat/journal_preset.feature index d8f03ca1ad1..3013aebac77 100644 --- a/mod/data/preset/journal/tests/behat/journal_preset.feature +++ b/mod/data/preset/journal/tests/behat/journal_preset.feature @@ -33,21 +33,21 @@ Feature: Users can use the Journal preset When I am on the "Student reflections" "data activity" page logged in as student1 Then I should see "Reflection created by student" And I should see "This is the content for the entry 1" - And "Actions" "icon" should exist in the "#journal-list" "css_element" + And "Actions" "button" should exist in the "#journal-list" "css_element" And I should see "Reflection created by teacher" And I should see "And this is the content for the entry 2" # Single view. And I select "Single view" from the "jump" singleselect And I should see "Reflection created by student" And I should see "This is the content for the entry 1" - And "Actions" "icon" should exist in the ".journal-single" "css_element" + And "Actions" "button" should exist in the ".journal-single" "css_element" And I should not see "Reflection created by teacher" And I should not see "And this is the content for the entry 2" And I follow "Next" And I should see "Reflection created by teacher" And I should see "And this is the content for the entry 2" # This student can't edit or delete this entry, so the Actions menu shouldn't be displayed. - And "Actions" "icon" should not exist in the ".journal-single" "css_element" + And "Actions" "button" should not exist in the ".journal-single" "css_element" And I should not see "Reflection created by student" And I should not see "This is the content for the entry 1" diff --git a/mod/data/preset/proposals/tests/behat/proposals_preset.feature b/mod/data/preset/proposals/tests/behat/proposals_preset.feature index 7deb633da53..ca6de0b16f7 100644 --- a/mod/data/preset/proposals/tests/behat/proposals_preset.feature +++ b/mod/data/preset/proposals/tests/behat/proposals_preset.feature @@ -33,7 +33,7 @@ Feature: Users can use the Proposals preset When I am on the "Student projects" "data activity" page logged in as student1 Then I should see "Project created by student" And "Summary 1" "text" should exist - And "Actions" "icon" should exist in the "#proposals-list" "css_element" + And "Actions" "button" should exist in the "#proposals-list" "css_element" And I should see "Project created by teacher" And "Summary 2" "text" should exist And I click on "Project created by student" "link" @@ -48,7 +48,7 @@ Feature: Users can use the Proposals preset And I should see "Summary 1" And I should see "Content for entry 1" And I should see "Pending" - And "Actions" "icon" should exist in the ".proposals-single" "css_element" + And "Actions" "button" should exist in the ".proposals-single" "css_element" And I should not see "Project created by teacher" And I should not see "Summary 2" And I should not see "And content for entry 2" @@ -59,7 +59,7 @@ Feature: Users can use the Proposals preset And I should see "And content for entry 2" And I should see "Rejected" # This student can't edit or delete this entry, so the Actions menu shouldn't be displayed. - And "Actions" "icon" should not exist in the ".proposals-single" "css_element" + And "Actions" "button" should not exist in the ".proposals-single" "css_element" And I should not see "Project created by student" And I should not see "Summary 1" And I should not see "Content for entry 1" diff --git a/mod/data/preset/resources/tests/behat/resources_preset.feature b/mod/data/preset/resources/tests/behat/resources_preset.feature index 6b53cbf6706..5aed5cb8bb5 100644 --- a/mod/data/preset/resources/tests/behat/resources_preset.feature +++ b/mod/data/preset/resources/tests/behat/resources_preset.feature @@ -36,7 +36,7 @@ Feature: Users can use the Resources preset And I should see "The book author" And I should see "http://myfavouritebook.cat" And I should not see "Book content" - And "Actions" "icon" should exist in the "#resources-list" "css_element" + And "Actions" "button" should exist in the "#resources-list" "css_element" And I should see "My favourite podcast" And I should see "Type2" And I should see "The podcast author" @@ -49,7 +49,7 @@ Feature: Users can use the Resources preset And I should see "The book author" And I should see "http://myfavouritebook.cat" And I should see "Book content" - And "Actions" "icon" should exist in the ".resources-single" "css_element" + And "Actions" "button" should exist in the ".resources-single" "css_element" And I should not see "My favourite podcast" And I should not see "Type2" And I should not see "The podcast author" @@ -62,7 +62,7 @@ Feature: Users can use the Resources preset And I should see "http://myfavouritepodcast.cat" And I should see "Podcast content" # This student can't edit or delete this entry, so the Actions menu shouldn't be displayed. - And "Actions" "icon" should not exist in the ".resources-single" "css_element" + And "Actions" "button" should not exist in the ".resources-single" "css_element" And I should not see "My favourite book" And I should not see "Type1" And I should not see "The book author" diff --git a/mod/data/tests/behat/data_presets.feature b/mod/data/tests/behat/data_presets.feature index 4d6de9ae3b6..203c52151e4 100644 --- a/mod/data/tests/behat/data_presets.feature +++ b/mod/data/tests/behat/data_presets.feature @@ -33,16 +33,11 @@ Feature: Users can view and manage data presets And I should see "Saved preset 2" And I should see "Saved preset by teacher1" # Plugin presets can't be removed. - And I should not see "Actions" in the "Image gallery" "table_row" + And the "Delete" item should not exist in the "Actions" action menu of the "Image gallery" "table_row" # The admin should be able to delete saved presets. - But I open the action menu in "Saved preset 1" "table_row" - And I should see "Delete" - And I press the escape key - And I open the action menu in "Saved preset 2" "table_row" - And I should see "Delete" - And I press the escape key - And I open the action menu in "Saved preset by teacher1" "table_row" - And I should see "Delete" + But the "Delete" item should exist in the "Actions" action menu of the "Saved preset 1" "table_row" + And the "Delete" item should exist in the "Actions" action menu of the "Saved preset 2" "table_row" + And the "Delete" item should exist in the "Actions" action menu of the "Saved preset by teacher1" "table_row" @javascript Scenario: Teachers can see and use presets @@ -57,12 +52,11 @@ Feature: Users can view and manage data presets And I should see "Saved preset by teacher1" And I should see "This preset has also a description" in the "Saved preset by teacher1" "table_row" # Plugin presets can't be removed. - And I should not see "Actions" in the "Image gallery" "table_row" + And the "Delete" item should not exist in the "Actions" action menu of the "Image gallery" "table_row" # Teachers should be able to delete their saved presets. - And I open the action menu in "Saved preset by teacher1" "table_row" - And I should see "Delete" + And the "Delete" item should exist in the "Actions" action menu of the "Saved preset by teacher1" "table_row" # Teachers can't delete the presets they haven't created. - And I should not see "Actions" in the "Saved preset 1" "table_row" + And the "Delete" item should not exist in the "Actions" action menu of the "Saved preset 1" "table_row" # The "Use this preset" button should be enabled only when a preset is selected. And the "Use this preset" "button" should be disabled And I click on "fullname" "radio" in the "Image gallery" "table_row" @@ -148,9 +142,9 @@ Feature: Users can view and manage data presets Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1 When I follow "Presets" # Plugin presets can't be edited. - Then I should not see "Actions" in the "Image gallery" "table_row" + Then the "Edit" item should not exist in the "Actions" action menu of the "Image gallery" "table_row" # Teachers can't edit the presets they haven't created. - And I should not see "Actions" in the "Saved preset 1" "table_row" + And the "Edit" item should not exist in the "Actions" action menu of the "Saved preset 1" "table_row" # Teachers should be able to edit their saved presets. And I open the action menu in "Saved preset by teacher1" "table_row" And I choose "Edit" in the open action menu @@ -254,12 +248,12 @@ Feature: Users can view and manage data presets And I should see "Saved preset 1" And I should see "Saved preset by teacher1" # Plugin presets can't be removed. - And I should not see "Actions" in the "Image gallery" "table_row" + And the "Delete" item should not exist in the "Actions" action menu of the "Image gallery" "table_row" # The teacher should not be able to delete presets saved by others. - And I should not see "Actions" in the "Saved preset 1" "table_row" + And the "Delete" item should not exist in the "Actions" action menu of the "Saved preset 1" "table_row" # The teacher should be able to delete their own preset. And I open the action menu in "Saved preset by teacher" "table_row" - And I follow "Delete" + And I choose "Delete" in the open action menu And I click on "Delete" "button" in the "Delete preset Saved preset by teacher1?" "dialogue" And I should see "Preset deleted" And I should not see "Saved preset by teacher1" @@ -295,14 +289,12 @@ Feature: Users can view and manage data presets Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1 When I follow "Presets" # Plugin presets can't be exported. - And I should not see "Actions" in the "Image gallery" "table_row" + And the "Export" item should not exist in the "Actions" action menu of the "Image gallery" "table_row" # The teacher should be able to export any saved preset. - And I open the action menu in "Saved preset by teacher1" "table_row" - Then I should see "Export" + And the "Export" item should exist in the "Actions" action menu of the "Saved preset by teacher1" "table_row" And following "Export" in the "Saved preset by teacher1" "table_row" should download a file that: | Contains file in zip | preset.xml | - And I open the action menu in "Saved preset 1" "table_row" - And I should see "Export" + And the "Export" item should exist in the "Actions" action menu of the "Saved preset 1" "table_row" And following "Export" in the "Saved preset 1" "table_row" should download a file that: | Contains file in zip | preset.xml | @@ -343,7 +335,7 @@ Feature: Users can view and manage data presets Given I am on the "Mountain landscapes" "data activity" page logged in as teacher1 And I follow "Presets" And I open the action menu in "" "table_row" - When I click on "Preview" "link" in the "" "table_row" + When I choose "Preview" in the open action menu Then I should see "Preview of " Examples: diff --git a/mod/data/tests/behat/tertiary_navigation.feature b/mod/data/tests/behat/tertiary_navigation.feature index a3e619f56a8..a1444ab42f2 100644 --- a/mod/data/tests/behat/tertiary_navigation.feature +++ b/mod/data/tests/behat/tertiary_navigation.feature @@ -44,39 +44,35 @@ Feature: Users can navigate through the database activity using the tertiary nav Scenario: The tertiary navigation in the Database page. Given I navigate to "Database" in current page administration # Teacher: List view. - And I should not see "List view" in the "data-listview-content" "region" - When I click on "Actions" "button" - Then I should see "Import entries" in the ".entriesactions" "css_element" - And I should see "Export entries" in the ".entriesactions" "css_element" - And I should see "Export to portfolio" in the ".entriesactions" "css_element" - And I press the escape key + Then I should not see "List view" in the "data-listview-content" "region" + And the "Import entries" item should exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" + And the "Export entries" item should exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" + And the "Export to portfolio" item should exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" # Teacher: Single view. And I set the field "View mode tertiary navigation" to "Single view" And I should not see "Single view" in the "data-singleview-content" "region" - And I click on "Actions" "button" - And I should see "Import entries" in the ".entriesactions" "css_element" - And I should see "Export entries" in the ".entriesactions" "css_element" - And I should not see "Export to portfolio" in the ".entriesactions" "css_element" + And the "Import entries" item should exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" + And the "Export entries" item should exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" + And the "Export to portfolio" item should not exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" # Teacher: Database without fields. And I am on the "Database without fields" "data activity" page - And I should not see "Actions" + And "Actions" "actionmenu" should not exist # Student without entries: List view. And I am on the "Test database name" "data activity" page logged in as student1 - And I should not see "Actions" + And "Actions" "actionmenu" should not exist in the ".tertiary-navigation" "css_element" # Student without entries: Single view. And I set the field "View mode tertiary navigation" to "Single view" - And I should not see "Actions" + And I should not see "Actions" in the ".tertiary-navigation" "css_element" # Student with entries: Single view. But the following "mod_data > entries" exist: | database | user | field1 | field2 | | data1 | student1 | Student entry 3 | Some content 3 | - And I should not see "Actions" + And I should not see "Actions" in the ".tertiary-navigation" "css_element" # Student with entries: List view. And I set the field "View mode tertiary navigation" to "List view" - And I click on "Actions" "button" - And I should not see "Import entries" in the ".entriesactions" "css_element" - And I should not see "Export entries" in the ".entriesactions" "css_element" - And I should see "Export to portfolio" in the ".entriesactions" "css_element" + And the "Import entries" item should not exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" + And the "Export entries" item should not exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" + And the "Export to portfolio" item should exist in the "Actions" action menu of the ".tertiary-navigation" "css_element" @javascript Scenario: The tertiary navigation in the Presets page. @@ -104,14 +100,11 @@ Feature: Users can navigate through the database activity using the tertiary nav And I should see "Preview of Saved preset by teacher1" And "Use this preset" "button" should exist - @javascript Scenario: The tertiary navigation in the Fields page. Given I navigate to "Fields" in current page administration - When I open the action menu in "field1" "table_row" - Then I should see "Edit" - And I should see "Delete" - And I press the escape key - And I should not see "Actions" + Then the "Edit" item should exist in the "Actions" action menu of the "field1" "table_row" + And the "Delete" item should exist in the "Actions" action menu of the "field1" "table_row" + And I should not see "Actions" in the ".tertiary-navigation" "css_element" @javascript Scenario: The tertiary navigation in the Templates page. diff --git a/mod/lti/classes/reportbuilder/local/systemreports/course_external_tools_list.php b/mod/lti/classes/reportbuilder/local/systemreports/course_external_tools_list.php index 5f8751c467e..54127f9cb1f 100644 --- a/mod/lti/classes/reportbuilder/local/systemreports/course_external_tools_list.php +++ b/mod/lti/classes/reportbuilder/local/systemreports/course_external_tools_list.php @@ -16,6 +16,7 @@ namespace mod_lti\reportbuilder\local\systemreports; +use core\output\html_writer; use core_reportbuilder\local\helpers\database; use core_reportbuilder\local\report\column; use mod_lti\reportbuilder\local\entities\tool_types; @@ -218,8 +219,13 @@ class course_external_tools_list extends system_report { // Build and display an action menu. $menu = new \action_menu(); - $menu->set_menu_trigger($OUTPUT->pix_icon('i/moremenu', get_string('actions', 'core')), - 'btn btn-icon d-flex align-items-center justify-content-center'); // TODO check 'actions' lang string with UX. + $triggerlabel = get_string('actions'); + $visuallyhiddenlabel = html_writer::span($triggerlabel, 'sr-only d-inline-block'); + $menu->set_menu_trigger( + $OUTPUT->pix_icon('i/moremenu', '') . $visuallyhiddenlabel, + 'btn btn-icon d-flex align-items-center justify-content-center' + ); + $menu->triggerattributes['title'] = $triggerlabel; $menu->add(new \action_menu_link( new \moodle_url('/mod/lti/coursetooledit.php', ['course' => $row->course, 'typeid' => $row->id]), diff --git a/mod/subsection/tests/behat/subsection_actionmenu.feature b/mod/subsection/tests/behat/subsection_actionmenu.feature index 5eb37ab1fd4..2c19147274a 100644 --- a/mod/subsection/tests/behat/subsection_actionmenu.feature +++ b/mod/subsection/tests/behat/subsection_actionmenu.feature @@ -28,7 +28,7 @@ Feature: The module menu replaces the delegated section menu Given I click on "Subsection1" "link" in the "region-main" "region" And I turn editing mode on # Open the action menu. - When I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + When I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" Then I should not see "Move right" And I should not see "Assign roles" And I should not see "Highlight" @@ -81,7 +81,7 @@ Feature: The module menu replaces the delegated section menu Then I should see "Subsection1" in the "h1" "css_element" And "Section 1" "text" should exist in the ".breadcrumb" "css_element" # Open the section header action menu. - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And "View" "link" should not exist in the "[data-region='header-actions-container']" "css_element" And I click on "Section 1" "link" in the ".breadcrumb" "css_element" # Section page. Section name should be the title. @@ -101,7 +101,7 @@ Feature: The module menu replaces the delegated section menu And I click on "Cancel" "button" And I am on the "C1 > Subsection1" "course > section" page # Subsection page. Open the section header action menu. - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And I choose "Edit settings" in the open action menu And the field "Section name" matches value "Subsection1" And I click on "Cancel" "button" @@ -120,7 +120,7 @@ Feature: The module menu replaces the delegated section menu And I should see "Text copied to clipboard" And I am on the "C1 > Subsection1" "course > section" page # Subsection page. Open the section header action menu. - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And I choose "Permalink" in the open action menu And I click on "Copy to clipboard" "link" And I should see "Text copied to clipboard" @@ -153,7 +153,7 @@ Feature: The module menu replaces the delegated section menu And "Subsection2" "link" should not exist in the "#region-main-box" "css_element" And I am on the "C1 > Subsection3" "course > section" page # Subsection page. Open the section header action menu. - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And I choose "Delete" in the open action menu And I click on "Delete" "button" in the "Delete subsection?" "dialogue" And I should not see "Subsection3" @@ -169,7 +169,7 @@ Feature: The module menu replaces the delegated section menu Given I am on the "C1 > Subsection1" "course > section" page And I should see "Hidden from students" # Subsection page. Open the section header action menu. - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And I choose "Show" in the open action menu And I should not see "Hidden from students" And I click on "Section 1" "link" in the ".breadcrumb" "css_element" @@ -236,5 +236,5 @@ Feature: The module menu replaces the delegated section menu And I should see "Move" # Subsection page. Move option should not exist. And I am on the "C1 > Subsection1" "course > section" page - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And "Move" "link" should not exist in the "[data-region='header-actions-container']" "css_element" diff --git a/mod/subsection/tests/behat/subsection_disabled_plugin.feature b/mod/subsection/tests/behat/subsection_disabled_plugin.feature index fc54005695b..d15e2fc476e 100644 --- a/mod/subsection/tests/behat/subsection_disabled_plugin.feature +++ b/mod/subsection/tests/behat/subsection_disabled_plugin.feature @@ -77,7 +77,7 @@ Feature: Courses should not lose subsection contents when mod_subsection is disa And I am on "Course 1" course homepage with editing mode on # Perform teacher actions instead of fast steps to validate delete # an orphaned subsection does not break the course. - And I click on "Edit" "icon" in the "Subsection1" "core_courseformat > Section actions menu" + And I click on "Edit" "button" in the "Subsection1" "core_courseformat > Section actions menu" When I choose "Delete" in the open action menu And I click on "Delete" "button" in the "Delete section?" "dialogue" Then I enable "subsection" "mod" plugin @@ -113,7 +113,7 @@ Feature: Courses should not lose subsection contents when mod_subsection is disa And I should see "Not available unless: You belong to a group in GX1" And I should not see "Edit restrictions" And I am on the "C1 > Subsection1" "course > section" page - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And I choose "Delete" in the open action menu And I click on "Delete" "button" in the "Delete section?" "dialogue" And I enable "subsection" "mod" plugin @@ -131,7 +131,7 @@ Feature: Courses should not lose subsection contents when mod_subsection is disa And I disable "subsection" "mod" plugin When I am on the "C1 > Subsection2" "course > section" page And I turn editing mode on - And I click on "Edit" "icon" in the "[data-region='header-actions-container']" "css_element" + And I click on "Edit" "button" in the "[data-region='header-actions-container']" "css_element" And I choose "Delete" in the open action menu And I click on "Delete" "button" in the "Delete section?" "dialogue" And I enable "subsection" "mod" plugin diff --git a/mod/subsection/tests/behat/subsection_navigation.feature b/mod/subsection/tests/behat/subsection_navigation.feature index 310bd4f6597..8097c547de7 100644 --- a/mod/subsection/tests/behat/subsection_navigation.feature +++ b/mod/subsection/tests/behat/subsection_navigation.feature @@ -66,7 +66,7 @@ Feature: Teachers navigate to subsections And I am on "Course 1" course homepage with editing mode on And I add the "Navigation" block if not present # Open all navigation nodes via keyboard because it does not use buttons/links chevrons. - And I click on "Actions menu" "link" in the "Navigation" "block" + And I click on "Actions menu" "menuitem" in the "Navigation" "block" And I press the escape key And I press the tab key And I press the multiply key diff --git a/question/bank/columnsortorder/tests/behat/admin_settings.feature b/question/bank/columnsortorder/tests/behat/admin_settings.feature index 0be07b34947..8d9fba9c068 100644 --- a/question/bank/columnsortorder/tests/behat/admin_settings.feature +++ b/question/bank/columnsortorder/tests/behat/admin_settings.feature @@ -33,8 +33,7 @@ Feature: Set default question bank column order and size Given I log in as "admin" And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration And "Created by" "table_row" should exist - When I click on "Actions menu" "link" in the "Created by" "table_row" - And I choose "Remove" in the open action menu + When I choose the "Remove" item in the "Actions menu" action menu of the "Created by" "table_row" Then "Created by" "table_row" should not exist And I reload the page And "Created by" "table_row" should not exist @@ -88,8 +87,7 @@ Feature: Set default question bank column order and size And I follow "Back" And "checkboxcustomcolumn" "table_row" should appear before "Comments" "table_row" And the field "Width of 'checkboxcustomcolumn' in pixels" matches value "200" - And I click on "Actions menu" "link" in the "checkboxcustomcolumn" "table_row" - And I choose "Remove" in the open action menu + And I choose the "Remove" item in the "Actions menu" action menu of the "checkboxcustomcolumn" "table_row" And "checkboxcustomcolumn" "table_row" should not exist And I follow "Preview" And "checkboxcustomcolumn" "qbank_columnsortorder > column header" should not exist @@ -130,8 +128,7 @@ Feature: Set default question bank column order and size And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration And "Field 1" "table_row" should exist And "Field 2" "table_row" should exist - And I click on "Actions menu" "link" in the "Field 1" "table_row" - And I choose "Remove" in the open action menu + And I choose the "Remove" item in the "Actions menu" action menu of the "Field 1" "table_row" # Delete a question custom field. And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration @@ -140,8 +137,7 @@ Feature: Set default question bank column order and size And I navigate to "Plugins > Question bank plugins > Column sort order" in site administration Then I should see "Column sort order" And "Field 2" "table_row" should exist - And I click on "Actions menu" "link" in the "Field 2" "table_row" - And I choose "Remove" in the open action menu + And I choose the "Remove" item in the "Actions menu" action menu of the "Field 2" "table_row" # Delete the question custom category. And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration diff --git a/question/bank/columnsortorder/tests/behat/question_bank.feature b/question/bank/columnsortorder/tests/behat/question_bank.feature index fed6ab56be4..4daf8f1f5ed 100644 --- a/question/bank/columnsortorder/tests/behat/question_bank.feature +++ b/question/bank/columnsortorder/tests/behat/question_bank.feature @@ -70,8 +70,7 @@ Feature: Set question bank column order and size Given I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1" And I apply question bank filter "Category" with value "Question category 1" And "Comments" "qbank_columnsortorder > column header" should exist - And I click on "Actions menu" "link" in the "Comments" "qbank_columnsortorder > column header" - And I choose "Remove" in the open action menu + And I choose the "Remove" item in the "Actions menu" action menu of the "Comments" "qbank_columnsortorder > column header" Then "Comments" "qbank_columnsortorder > column header" should not exist And I reload the page And "Comments" "qbank_columnsortorder > column header" should not exist @@ -90,8 +89,7 @@ Feature: Set question bank column order and size Given I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1" And I apply question bank filter "Category" with value "Question category 1" And the "style" attribute of "Question" "qbank_columnsortorder > column header" should contain "width: 300px" - When I click on "Actions menu" "link" in the "Question" "qbank_columnsortorder > column header" - And I choose "Resize" in the open action menu + When I choose the "Resize" item in the "Actions menu" action menu of the "Question" "qbank_columnsortorder > column header" And I set the field "Column width (pixels)" to "400" And I press "Save changes" Then the "style" attribute of "Question" "qbank_columnsortorder > column header" should contain "width: 400px" @@ -113,8 +111,7 @@ Feature: Set question bank column order and size Given I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1" And I apply question bank filter "Category" with value "Question category 1" And "Comments" "qbank_columnsortorder > column header" should appear before "Question" "qbank_columnsortorder > column header" - When I click on "Actions menu" "link" in the "Comments" "qbank_columnsortorder > column header" - And I choose "Move" in the open action menu + When I choose the "Move" item in the "Actions menu" action menu of the "Comments" "qbank_columnsortorder > column header" And I follow "After \"Question\"" Then "Comments" "qbank_columnsortorder > column header" should appear after "Question" "qbank_columnsortorder > column header" And I reload the page @@ -152,10 +149,8 @@ Feature: Set question bank column order and size | Field 2 | Category for test | text | f2 | {"visibility":"2"} | And I am on the "Test quiz Q001" "mod_quiz > question bank" page logged in as "teacher1" And I apply question bank filter "Category" with value "Question category 1" - And I click on "Actions menu" "link" in the "Field 1" "qbank_columnsortorder > column header" - And I choose "Remove" in the open action menu - And I click on "Actions menu" "link" in the "Field 2" "qbank_columnsortorder > column header" - And I choose "Remove" in the open action menu + And I choose the "Remove" item in the "Actions menu" action menu of the "Field 1" "qbank_columnsortorder > column header" + And I choose the "Remove" item in the "Actions menu" action menu of the "Field 2" "qbank_columnsortorder > column header" And "Field 2" "qbank_columnsortorder > column header" should not exist # Delete a question custom field. diff --git a/reportbuilder/classes/table/system_report_table.php b/reportbuilder/classes/table/system_report_table.php index d7c108a6de5..bdf31b6e040 100644 --- a/reportbuilder/classes/table/system_report_table.php +++ b/reportbuilder/classes/table/system_report_table.php @@ -259,10 +259,7 @@ class system_report_table extends base_report_table { global $OUTPUT; $menu = new action_menu(); - $menu->set_menu_trigger( - $OUTPUT->pix_icon('i/menu', get_string('actions', 'core_reportbuilder')), - 'btn btn-icon d-flex align-items-center justify-content-center no-caret', - ); + $menu->set_kebab_trigger(get_string('actions', 'core_reportbuilder')); $actions = array_filter($this->report->get_actions(), function($action) use ($row) { // Only return dividers and action items who can be displayed for current users.