Commit 701ae1eb authored by Tim Hunt's avatar Tim Hunt
Browse files

MDL-66816 question bank: replace row of edit icons with an Edit menu

parent aaff6692
......@@ -639,9 +639,10 @@ $CFG->admin = 'admin';
// to check the latest default in question/classes/bank/view.php before setting this.
//
// $CFG->questionbankcolumns = 'checkbox_column,question_type_column,'
// . 'question_name_idnumber_tags_column,tags_action_column,edit_action_column,'
// . 'copy_action_column,preview_action_column,delete_action_column,'
// . 'creator_name_column,modifier_name_column';
// . 'question_name_idnumber_tags_column,'
// . 'tags_action_column,edit_action_column,copy_action_column,'
// . 'preview_action_column,delete_action_column,export_xml_action_column,'
// . 'creator_name_column,modifier_name_column,edit_menu_column';
//
// Forum summary report
//
......
......@@ -157,6 +157,7 @@ $string['eventquestionsexported'] = 'Questions exported';
$string['eventquestionsimported'] = 'Questions imported';
$string['eventquestionupdated'] = 'Question updated';
$string['export'] = 'Export';
$string['exportasxml'] = 'Export as Moodle XML';
$string['exportcategory'] = 'Export category';
$string['exportcategory_help'] = 'This setting determines the category from which the exported questions will be taken.
......
......@@ -4200,32 +4200,32 @@ class action_menu implements renderable, templatable {
/**
* An icon to use for the toggling the secondary menu (dropdown).
* @var actionicon
* @var pix_icon
*/
public $actionicon;
/**
* Any text to use for the toggling the secondary menu (dropdown).
* @var menutrigger
* @var string
*/
public $menutrigger = '';
/**
* Any extra classes for toggling to the secondary menu.
* @var triggerextraclasses
* @var string
*/
public $triggerextraclasses = '';
/**
* Place the action menu before all other actions.
* @var prioritise
* @var bool
*/
public $prioritise = false;
/**
* Constructs the action menu with the given items.
*
* @param array $actions An array of actions.
* @param array $actions An array of actions (action_menu_link|pix_icon|string).
*/
public function __construct(array $actions = array()) {
static $initialised = 0;
......@@ -4259,7 +4259,6 @@ class action_menu implements renderable, templatable {
* Sets the label for the menu trigger.
*
* @param string $label The text
* @return null
*/
public function set_action_label($label) {
$this->actionlabel = $label;
......@@ -4270,7 +4269,6 @@ class action_menu implements renderable, templatable {
*
* @param string $trigger The text
* @param string $extraclasses Extra classes to style the secondary menu toggle.
* @return null
*/
public function set_menu_trigger($trigger, $extraclasses = '') {
$this->menutrigger = $trigger;
......
......@@ -986,7 +986,6 @@ table.quizreviewsummary td.cell {
table#categoryquestions {
width: 100%;
overflow: hidden;
table-layout: fixed;
}
......@@ -1002,6 +1001,10 @@ table#categoryquestions {
padding: 0;
}
#categoryquestions .editmenu {
width: 5em;
}
#categoryquestions .qtype {
text-align: center;
}
......
......@@ -14,15 +14,24 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A base class for actions that are an icon that lets you manipulate the question in some way.
*
* @package core_question
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* A base class for actions that are an icon that lets you manipulate the question in some way.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class action_column_base extends column_base {
protected function get_title() {
......
......@@ -14,15 +14,24 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A column with a checkbox for each question with name q{questionid}.
*
* @package core_question
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
use core\output\checkbox_toggleall;
/**
* A column with a checkbox for each question with name q{questionid}.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class checkbox_column extends column_base {
......
......@@ -15,23 +15,23 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Base class for representing a column in a {@link question_bank_view}.
*
* @package moodlecore
* @subpackage questionbank
* @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package core_question
* @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* Base class for representing a column in a {@link question_bank_view}.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class column_base {
/**
* @var view $qbank the question bank view we are helping to render.
......
......@@ -14,16 +14,25 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Question bank column for the duplicate action icon.
*
* @package core_question
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* Question bank column for the duplicate action icon.
*
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class copy_action_column extends action_column_base {
class copy_action_column extends menu_action_column_base {
/** @var string avoids repeated calls to get_string('duplicate'). */
protected $strcopy;
......@@ -36,13 +45,14 @@ class copy_action_column extends action_column_base {
return 'copyaction';
}
protected function display_content($question, $rowclasses) {
protected function get_url_icon_and_label(\stdClass $question): array {
// To copy a question, you need permission to add a question in the same
// category as the existing question, and ability to access the details of
// the question being copied.
if (question_has_capability_on($question, 'add') &&
(question_has_capability_on($question, 'edit') || question_has_capability_on($question, 'view'))) {
$this->print_icon('t/copy', $this->strcopy, $this->qbank->copy_question_url($question->id));
return [$this->qbank->copy_question_moodle_url($question->id), 't/copy', $this->strcopy];
}
return [null, null, null];
}
}
......@@ -14,16 +14,24 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A column type for the name of the question creator.
*
* @package core_question
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* A column type for the name of the question creator.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class creator_name_column extends column_base {
public function get_name() {
return 'creatorname';
......
......@@ -14,16 +14,25 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* action to delete (or hide) a question, or restore a previously hidden question.
*
* @package core_question
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* action to delete (or hide) a question, or restore a previously hidden question.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_action_column extends action_column_base {
class delete_action_column extends menu_action_column_base {
protected $strdelete;
protected $strrestore;
......@@ -37,16 +46,30 @@ class delete_action_column extends action_column_base {
return 'deleteaction';
}
protected function display_content($question, $rowclasses) {
if (question_has_capability_on($question, 'edit')) {
if ($question->hidden) {
$url = new \moodle_url($this->qbank->base_url(), array('unhide' => $question->id, 'sesskey' => sesskey()));
$this->print_icon('t/restore', $this->strrestore, $url);
} else {
$url = new \moodle_url($this->qbank->base_url(), array('deleteselected' => $question->id, 'q' . $question->id => 1,
'sesskey' => sesskey()));
$this->print_icon('t/delete', $this->strdelete, $url);
}
/**
* Work out the info required to display this action, if appropriate.
*
* If the action is not appropriate to this question, return [null, null, null].
*
* Otherwise return an array with three elements:
* moodel_url $url the URL to perform the action.
* string $icon the icon name. E.g. 't/delete'.
* string $label the label to display.
*
* @param object $question the row from the $question table, augmented with extra information.
* @return array [$url, $label, $icon] as above.
*/
protected function get_url_icon_and_label(\stdClass $question): array {
if (!question_has_capability_on($question, 'edit')) {
return [null, null, null];
}
if ($question->hidden) {
$url = new \moodle_url($this->qbank->base_url(), array('unhide' => $question->id, 'sesskey' => sesskey()));
return [$url, 't/restore', $this->strrestore];
} else {
$url = new \moodle_url($this->qbank->base_url(), array('deleteselected' => $question->id, 'q' . $question->id => 1,
'sesskey' => sesskey()));
return [$url, 't/delete', $this->strdelete];
}
}
......
......@@ -14,21 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Base class for question bank columns that just contain an action icon.
*
* @package core_question
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* Base class for question bank columns that just contain an action icon.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_action_column extends action_column_base {
class edit_action_column extends menu_action_column_base {
protected $stredit;
protected $strview;
public function init() {
parent::init();
$this->stredit = get_string('edit');
$this->stredit = get_string('editquestion', 'question');
$this->strview = get_string('view');
}
......@@ -36,11 +46,13 @@ class edit_action_column extends action_column_base {
return 'editaction';
}
protected function display_content($question, $rowclasses) {
protected function get_url_icon_and_label(\stdClass $question): array {
if (question_has_capability_on($question, 'edit')) {
$this->print_icon('t/edit', $this->stredit, $this->qbank->edit_question_url($question->id));
return [$this->qbank->edit_question_moodle_url($question->id), 't/edit', $this->stredit];
} else if (question_has_capability_on($question, 'view')) {
$this->print_icon('i/info', $this->strview, $this->qbank->edit_question_url($question->id));
return [$this->qbank->edit_question_moodle_url($question->id), 'i/info', $this->strview];
} else {
return [null, null, null];
}
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A question bank column which gathers together all the actions into a menu.
*
* @package core_question
* @copyright 2019 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* A question bank column which gathers together all the actions into a menu.
*
* This question bank column, if added to the question bank, will
* replace all of the other columns which implement the
* {@link menuable_action} interface and replace them with a single
* column containing an Edit menu.
*
* @copyright 2019 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_menu_column extends column_base {
/**
* @var menuable_action[]
*/
protected $actions;
/**
* Set up the list of actions that should be shown in the menu.
*
* This takes a list of column object (the list from a question
* bank view). It extracts all the ones that should go in the menu
* and stores them for later use. Then it returns the remaining columns.
*
* @param column_base[] $allcolumns a set of columns.
* @return column_base[] the non-action columns from the set.
*/
public function claim_menuable_columns($allcolumns) {
$remainingcolumns = [];
foreach ($allcolumns as $key => $column) {
if ($column instanceof menuable_action) {
$this->actions[$key] = $column;
} else {
$remainingcolumns[$key] = $column;
}
}
return $remainingcolumns;
}
protected function get_title() {
return get_string('actions');
}
public function get_name() {
return 'editmenu';
}
protected function display_content($question, $rowclasses) {
global $OUTPUT;
$menu = new \action_menu();
$menu->set_menu_trigger(get_string('edit'));
$menu->set_alignment(\action_menu::TL, \action_menu::BL);
foreach ($this->actions as $actioncolumn) {
$action = $actioncolumn->get_action_menu_link($question);
if ($action) {
$menu->add($action);
}
}
echo $OUTPUT->render($menu);
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Question bank column export the question in Moodle XML format.
*
* @package core_question
* @copyright 2019 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* Question bank column export the question in Moodle XML format.
*
* @copyright 2019 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class export_xml_action_column extends menu_action_column_base {
/** @var string avoids repeated calls to get_string('duplicate'). */
protected $strexportasxml;
public function init() {
parent::init();
$this->strexportasxml = get_string('exportasxml', 'question');
}
public function get_name() {
return 'exportasxmlaction';
}
protected function get_url_icon_and_label(\stdClass $question): array {
if (!question_has_capability_on($question, 'view')) {
return [null, null, null];
}
return [question_get_export_single_question_url($question),
't/download', $this->strexportasxml];
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Base class to make it easier to implement actions that are menuable_actions.
*
* @package core_question
* @copyright 2019 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_question\bank;
defined('MOODLE_INTERNAL') || die();
/**
* Base class to make it easier to implement actions that are menuable_actions.
*
* Use this class if your action is simple (defined by just a URL, label and icon).
* If your action is not simple enough to fit into the pattern that this
* class implements, then you will have to implement the menuable_action
* interface yourself.
*
* @copyright 2019 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class menu_action_column_base extends action_column_base implements menuable_action {
/**
* Get the information required to display this action either as a menu item or a separate action column.
*
* If this action cannot apply to this question (e.g. because the user does not have
* permission, then return [null, null, null].
*
* @param \stdClass $question the row from the $question table, augmented with extra information.
* @return array with three elements.
* $url - the URL to perform the action.
* $icon - the icon for this action. E.g. 't/delete'.
* $label - text label to display in the UI (either in the menu, or as a tool-tip on the icon)
*/
abstract protected function get_url_icon_and_label(\stdClass $question): array;
protected function display_content($question, $rowclasses) {
[$url, $icon, $label] = $this->get_url_icon_and_label($question);
if ($url) {
$this->print_icon($icon, $label, $url);
}
}
public function get_action_menu_link(\stdClass $question): ?\action_menu_link {
[$url, $icon, $label] = $this->get_url_icon_and_label($question);
if (!$url) {
return null;
}
return new \action_menu_link_secondary($url, new \pix_icon($icon, ''), $label);
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,