From 5aa749f0c68717c48d4872941b233f7b03be5658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Mart=C3=ADn?= Date: Tue, 23 Apr 2024 16:17:23 +0200 Subject: [PATCH] MDL-81744 mod_feedback: Improve 'Templates' page UI - Add new actions to the table in a single action menu. - Refactor 'usetemplate' module to allow to be called multiple times in the same page. - Remove 'mode' parameter and logic from template management. - Add a heading to template preview page. - Add 'Actions' menu to the template preview page. - Fix related behat scenarios. --- .upgradenotes/MDL-81744-2024100308251816.yml | 11 ++ mod/feedback/amd/build/usetemplate.min.js | 2 +- mod/feedback/amd/build/usetemplate.min.js.map | 2 +- mod/feedback/amd/src/usetemplate.js | 64 +++++---- .../classes/form/create_template_form.php | 3 +- .../classes/output/edit_action_bar.php | 5 +- .../output/edit_template_action_bar.php | 66 +++++++--- mod/feedback/classes/templates_table.php | 123 +++++++++++++----- mod/feedback/lang/en/feedback.php | 14 +- mod/feedback/lib.php | 2 +- mod/feedback/manage_templates.php | 17 +-- .../templates/main_action_menu.mustache | 28 ---- mod/feedback/templates/use_template.mustache | 37 ------ mod/feedback/tests/behat/templates.feature | 90 +++++++------ mod/feedback/use_templ.php | 7 +- mod/feedback/use_templ_form.php | 6 + theme/boost/scss/moodle/modules.scss | 20 +++ theme/boost/style/moodle.css | 12 ++ theme/classic/style/moodle.css | 12 ++ 19 files changed, 311 insertions(+), 210 deletions(-) create mode 100644 .upgradenotes/MDL-81744-2024100308251816.yml delete mode 100644 mod/feedback/templates/use_template.mustache diff --git a/.upgradenotes/MDL-81744-2024100308251816.yml b/.upgradenotes/MDL-81744-2024100308251816.yml new file mode 100644 index 0000000000000..e14b45d57d896 --- /dev/null +++ b/.upgradenotes/MDL-81744-2024100308251816.yml @@ -0,0 +1,11 @@ +issueNumber: MDL-81744 +notes: + mod_feedback: + - message: >- + The 'mode' parameter has been deprecated from 'edit_template_action_bar' + and 'templates_table' contructors. + type: deprecated + - message: >- + The 'use_template' template has been removed as it is not needed + anymore. + type: removed diff --git a/mod/feedback/amd/build/usetemplate.min.js b/mod/feedback/amd/build/usetemplate.min.js index 622370d3ab12d..9668d48db9f71 100644 --- a/mod/feedback/amd/build/usetemplate.min.js +++ b/mod/feedback/amd/build/usetemplate.min.js @@ -5,6 +5,6 @@ define("mod_feedback/usetemplate",["exports","core_form/modalform","core/notific * @module mod_feedback/usetemplate * @copyright 2021 Peter Dias * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=_interopRequireDefault(_modalform),_notification=_interopRequireDefault(_notification);const selectors_modaltrigger='[data-action="usetemplate"]';_exports.init=()=>{const trigger=document.querySelector(selectors_modaltrigger);trigger.addEventListener("click",(event=>{event.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.getString)("use_this_template","mod_feedback")},formClass:"mod_feedback\\form\\use_template_form",args:{id:trigger.getAttribute("data-dataid"),templateid:trigger.getAttribute("data-templateid")},saveButtonText:(0,_str.getString)("save","core")});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{event.detail.result?window.location.assign(event.detail.url):_notification.default.addNotification({type:"error",message:(0,_str.getString)("saving_failed","mod_feedback")})})),modalForm.show()}))}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=_interopRequireDefault(_modalform),_notification=_interopRequireDefault(_notification);const selectors_modaltrigger='[data-action="usetemplate"]';let initialized=!1;_exports.init=()=>{initialized||(document.addEventListener("click",(event=>{const trigger=event.target.closest(selectors_modaltrigger);if(trigger){event.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.getString)("use_this_template","mod_feedback")},formClass:"mod_feedback\\form\\use_template_form",args:{id:trigger.getAttribute("data-dataid"),templateid:trigger.getAttribute("data-templateid")},saveButtonText:(0,_str.getString)("save","core")});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{event.detail.result?window.location.assign(event.detail.url):_notification.default.addNotification({type:"error",message:(0,_str.getString)("saving_failed","mod_feedback")})})),modalForm.show()}})),initialized=!0)}})); //# sourceMappingURL=usetemplate.min.js.map \ No newline at end of file diff --git a/mod/feedback/amd/build/usetemplate.min.js.map b/mod/feedback/amd/build/usetemplate.min.js.map index da2f9b224bd37..991899b975eac 100644 --- a/mod/feedback/amd/build/usetemplate.min.js.map +++ b/mod/feedback/amd/build/usetemplate.min.js.map @@ -1 +1 @@ -{"version":3,"file":"usetemplate.min.js","sources":["../src/usetemplate.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Javascript module for using an existing template\n *\n * @module mod_feedback/usetemplate\n * @copyright 2021 Peter Dias\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {getString} from 'core/str';\n\nconst selectors = {\n modaltrigger: '[data-action=\"usetemplate\"]',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n const trigger = document.querySelector(selectors.modaltrigger);\n\n trigger.addEventListener('click', event => {\n event.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('use_this_template', 'mod_feedback'),\n },\n formClass: 'mod_feedback\\\\form\\\\use_template_form',\n args: {\n id: trigger.getAttribute('data-dataid'),\n templateid: trigger.getAttribute('data-templateid')\n },\n saveButtonText: getString('save', 'core')\n });\n\n // Show a toast notification when the form is submitted.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n window.location.assign(event.detail.url);\n } else {\n Notification.addNotification({\n type: 'error',\n message: getString('saving_failed', 'mod_feedback')\n });\n }\n });\n\n modalForm.show();\n });\n};\n"],"names":["selectors","trigger","document","querySelector","addEventListener","event","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","id","getAttribute","templateid","saveButtonText","events","FORM_SUBMITTED","detail","result","window","location","assign","url","addNotification","type","message","show"],"mappings":";;;;;;;0LA2BMA,uBACY,4CAME,WACVC,QAAUC,SAASC,cAAcH,wBAEvCC,QAAQG,iBAAiB,SAASC,QAC9BA,MAAMC,uBAEAC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,kBAAU,oBAAqB,iBAE1CC,UAAW,wCACXC,KAAM,CACFC,GAAIZ,QAAQa,aAAa,eACzBC,WAAYd,QAAQa,aAAa,oBAErCE,gBAAgB,kBAAU,OAAQ,UAItCT,UAAUH,iBAAiBG,UAAUU,OAAOC,gBAAgBb,QACpDA,MAAMc,OAAOC,OACbC,OAAOC,SAASC,OAAOlB,MAAMc,OAAOK,2BAEvBC,gBAAgB,CACzBC,KAAM,QACNC,SAAU,kBAAU,gBAAiB,qBAKjDpB,UAAUqB"} \ No newline at end of file +{"version":3,"file":"usetemplate.min.js","sources":["../src/usetemplate.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Javascript module for using an existing template\n *\n * @module mod_feedback/usetemplate\n * @copyright 2021 Peter Dias\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {getString} from 'core/str';\n\nconst selectors = {\n modaltrigger: '[data-action=\"usetemplate\"]',\n};\n\nlet initialized = false;\n\n/**\n * Initialize module\n */\nexport const init = () => {\n\n if (initialized) {\n // We already added the event listeners (can be called multiple times).\n return;\n }\n\n document.addEventListener('click', event => {\n // Use the template.\n const trigger = event.target.closest(selectors.modaltrigger);\n if (trigger) {\n event.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('use_this_template', 'mod_feedback'),\n },\n formClass: 'mod_feedback\\\\form\\\\use_template_form',\n args: {\n id: trigger.getAttribute('data-dataid'),\n templateid: trigger.getAttribute('data-templateid')\n },\n saveButtonText: getString('save', 'core')\n });\n\n // Show a toast notification when the form is submitted.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n window.location.assign(event.detail.url);\n } else {\n Notification.addNotification({\n type: 'error',\n message: getString('saving_failed', 'mod_feedback')\n });\n }\n });\n\n modalForm.show();\n }\n });\n\n initialized = true;\n};\n"],"names":["selectors","initialized","document","addEventListener","event","trigger","target","closest","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","id","getAttribute","templateid","saveButtonText","events","FORM_SUBMITTED","detail","result","window","location","assign","url","addNotification","type","message","show"],"mappings":";;;;;;;0LA2BMA,uBACY,kCAGdC,aAAc,gBAKE,KAEZA,cAKJC,SAASC,iBAAiB,SAASC,cAEzBC,QAAUD,MAAME,OAAOC,QAAQP,2BACjCK,QAAS,CACTD,MAAMI,uBAEAC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,kBAAU,oBAAqB,iBAE1CC,UAAW,wCACXC,KAAM,CACFC,GAAIV,QAAQW,aAAa,eACzBC,WAAYZ,QAAQW,aAAa,oBAErCE,gBAAgB,kBAAU,OAAQ,UAItCT,UAAUN,iBAAiBM,UAAUU,OAAOC,gBAAgBhB,QACpDA,MAAMiB,OAAOC,OACbC,OAAOC,SAASC,OAAOrB,MAAMiB,OAAOK,2BAEvBC,gBAAgB,CACzBC,KAAM,QACNC,SAAU,kBAAU,gBAAiB,qBAKjDpB,UAAUqB,WAIlB7B,aAAc"} \ No newline at end of file diff --git a/mod/feedback/amd/src/usetemplate.js b/mod/feedback/amd/src/usetemplate.js index 507da7d8764f2..f1f18dbb8b42e 100644 --- a/mod/feedback/amd/src/usetemplate.js +++ b/mod/feedback/amd/src/usetemplate.js @@ -29,39 +29,51 @@ const selectors = { modaltrigger: '[data-action="usetemplate"]', }; +let initialized = false; + /** * Initialize module */ export const init = () => { - const trigger = document.querySelector(selectors.modaltrigger); - trigger.addEventListener('click', event => { - event.preventDefault(); + if (initialized) { + // We already added the event listeners (can be called multiple times). + return; + } + + document.addEventListener('click', event => { + // Use the template. + const trigger = event.target.closest(selectors.modaltrigger); + if (trigger) { + event.preventDefault(); - const modalForm = new ModalForm({ - modalConfig: { - title: getString('use_this_template', 'mod_feedback'), - }, - formClass: 'mod_feedback\\form\\use_template_form', - args: { - id: trigger.getAttribute('data-dataid'), - templateid: trigger.getAttribute('data-templateid') - }, - saveButtonText: getString('save', 'core') - }); + const modalForm = new ModalForm({ + modalConfig: { + title: getString('use_this_template', 'mod_feedback'), + }, + formClass: 'mod_feedback\\form\\use_template_form', + args: { + id: trigger.getAttribute('data-dataid'), + templateid: trigger.getAttribute('data-templateid') + }, + saveButtonText: getString('save', 'core') + }); - // Show a toast notification when the form is submitted. - modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => { - if (event.detail.result) { - window.location.assign(event.detail.url); - } else { - Notification.addNotification({ - type: 'error', - message: getString('saving_failed', 'mod_feedback') - }); - } - }); + // Show a toast notification when the form is submitted. + modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => { + if (event.detail.result) { + window.location.assign(event.detail.url); + } else { + Notification.addNotification({ + type: 'error', + message: getString('saving_failed', 'mod_feedback') + }); + } + }); - modalForm.show(); + modalForm.show(); + } }); + + initialized = true; }; diff --git a/mod/feedback/classes/form/create_template_form.php b/mod/feedback/classes/form/create_template_form.php index a28e2b11dbf80..af9ec81e03468 100644 --- a/mod/feedback/classes/form/create_template_form.php +++ b/mod/feedback/classes/form/create_template_form.php @@ -44,11 +44,12 @@ public function definition() { get_string('name', 'feedback'), ['maxlength' => '200', 'size' => '50']); $mform->setType('templatename', PARAM_TEXT); + $mform->addRule('templatename', null, 'required', null, 'client'); if (has_capability('mod/feedback:createpublictemplate', context_system::instance())) { $mform->addElement('checkbox', 'ispublic', '', - get_string('public', 'feedback')); + get_string('availableforallcourses', 'feedback')); } } diff --git a/mod/feedback/classes/output/edit_action_bar.php b/mod/feedback/classes/output/edit_action_bar.php index a3a9bbc4472b5..39131df093bcf 100644 --- a/mod/feedback/classes/output/edit_action_bar.php +++ b/mod/feedback/classes/output/edit_action_bar.php @@ -95,8 +95,9 @@ private function get_edit_actions_menu(): action_menu { $actionsselect = new action_menu(); $actionsselect->set_menu_trigger(get_string('actions'), 'btn btn-outline-primary'); + $hasitems = $DB->record_exists('feedback_item', ['feedback' => $this->feedback->id]); // Export. - if ($DB->record_exists('feedback_item', ['feedback' => $this->feedback->id])) { + if ($hasitems) { $exporturl = new moodle_url('/mod/feedback/export.php', $this->urlparams + ['action' => 'exportfile']); $actionsselect->add(new action_menu_link( $exporturl, @@ -119,7 +120,7 @@ private function get_edit_actions_menu(): action_menu { $cancreatetemplates = has_any_capability([ 'mod/feedback:createprivatetemplate', 'mod/feedback:createpublictemplate'], \context_module::instance($this->cmid)); - if ($cancreatetemplates) { + if ($cancreatetemplates && $hasitems) { $PAGE->requires->js_call_amd('mod_feedback/createtemplate', 'init'); $actionsselect->add(new action_menu_link( new moodle_url('#'), diff --git a/mod/feedback/classes/output/edit_template_action_bar.php b/mod/feedback/classes/output/edit_template_action_bar.php index 4e60246162375..bb9282c2450c5 100644 --- a/mod/feedback/classes/output/edit_template_action_bar.php +++ b/mod/feedback/classes/output/edit_template_action_bar.php @@ -20,6 +20,9 @@ use context_system; use moodle_url; use action_link; +use action_menu; +use action_menu_link; +use pix_icon; /** * Class actionbar - Display the action bar @@ -31,19 +34,22 @@ class edit_template_action_bar extends base_action_bar { /** @var int $templateid The template that is being edited/used */ private $templateid; - /** @var string $mode The type of view we are dealing with */ - private $mode; /** * edit_template_action_bar constructor. * @param int $cmid * @param int $templateid - * @param string $mode + * @param string|null $mode This parameter has been deprecated since 4.5 and should not be used anymore. */ - public function __construct(int $cmid, int $templateid, string $mode) { + public function __construct(int $cmid, int $templateid, ?string $mode = null) { + if ($mode !== null) { + debugging( + 'The age argument has been deprecated. Please remove it from your method calls.', + DEBUG_DEVELOPER, + ); + } parent::__construct($cmid); $this->templateid = $templateid; - $this->mode = $mode; } /** @@ -52,35 +58,57 @@ public function __construct(int $cmid, int $templateid, string $mode) { * @return array */ public function get_items(): array { - global $DB; - $additionalparams = ($this->mode ? ['mode' => $this->mode] : []); - $templateurl = new moodle_url('/mod/feedback/manage_templates.php', $this->urlparams + $additionalparams); + global $DB, $OUTPUT, $PAGE; + + $templateurl = new moodle_url('/mod/feedback/manage_templates.php', $this->urlparams); + $template = $DB->get_record('feedback_template', array('id' => $this->templateid), '*', MUST_EXIST); + + // Back button. $items['left'][]['actionlink'] = new action_link($templateurl, get_string('back'), null, ['class' => 'btn btn-secondary']); + // Actions. if (has_capability('mod/feedback:edititems', $this->context)) { - $items['usetemplate'] = $this->urlparams + [ - 'templateid' => $this->templateid - ]; + $actionsselect = new action_menu(); + $actionsselect->set_menu_trigger(get_string('actions'), 'btn btn-outline-primary'); + $PAGE->requires->js_call_amd('mod_feedback/usetemplate', 'init'); + + // Use template. + $actionsselect->add(new action_menu_link( + new moodle_url('#'), + new pix_icon('i/files', get_string('preview')), + get_string('use_this_template', 'mod_feedback'), + false, + ['data-action' => 'usetemplate', 'data-dataid' => $this->cmid, 'data-templateid' => $this->templateid], + )); } - $template = $DB->get_record('feedback_template', array('id' => $this->templateid), '*', MUST_EXIST); - $systemcontext = context_system::instance(); + // Delete. $showdelete = has_capability('mod/feedback:deletetemplate', $this->context); if ($template->ispublic) { - $showdelete = has_capability('mod/feedback:createpublictemplate', $systemcontext) && - has_capability('mod/feedback:deletetemplate', $systemcontext); + $showdelete = has_all_capabilities( + ['mod/feedback:createpublictemplate', 'mod/feedback:deletetemplate'], + context_system::instance() + ); } - if ($showdelete) { - $params = $this->urlparams + $additionalparams + [ + $params = $this->urlparams + [ 'deletetemplate' => $this->templateid, 'sesskey' => sesskey() ]; $deleteurl = new moodle_url('/mod/feedback/manage_templates.php', $params); - $deleteaction = new confirm_action(get_string('confirmdeletetemplate', 'feedback')); - $items['export'] = new action_link($deleteurl, get_string('delete'), $deleteaction, ['class' => 'btn btn-secondary']); + $deleteaction = new action_link( + $deleteurl, + get_string('delete'), + new confirm_action(get_string('confirmdeletetemplate', 'feedback')), + ['class' => 'text-danger'], + new pix_icon('t/delete', get_string('delete_template', 'feedback')), + ); + $deleteaction->primary = false; + $actionsselect->add($deleteaction); } + $items['actionsselect'] = count($actionsselect->get_primary_actions()) > 0 ? $actionsselect : null; + return $items; } } diff --git a/mod/feedback/classes/templates_table.php b/mod/feedback/classes/templates_table.php index 35d10c5be4805..5bca5ec2f9ca6 100644 --- a/mod/feedback/classes/templates_table.php +++ b/mod/feedback/classes/templates_table.php @@ -24,6 +24,12 @@ defined('MOODLE_INTERNAL') || die(); +use \core\output\notification; +use \core\output\action_menu; +use \core\output\action_link; +use \core\output\action_menu\link_secondary; +use \core\output\actions\confirm_action; + global $CFG; require_once($CFG->libdir . '/tablelib.php'); @@ -35,30 +41,34 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class mod_feedback_templates_table extends flexible_table { - /** @var string|null Indicate whether we are managing template or not. */ - private $mode; + /** @var int|null The module id. */ + private $cmid; /** * Constructor * @param int $uniqueid all tables have to have a unique id, this is used * as a key when storing table properties like sort order in the session. * @param moodle_url $baseurl - * @param string $mode Indicate whether we are managing templates + * @param string|null $mode This parameter has been deprecated since 4.5 and should not be used anymore. */ public function __construct($uniqueid, $baseurl, ?string $mode = null) { - parent::__construct($uniqueid); - $this->mode = $mode; - $tablecolumns = array('template'); - if ($this->mode) { - $tablecolumns[] = 'actions'; + if ($mode !== null) { + debugging( + 'The age argument has been deprecated. Please remove it from your method calls.', + DEBUG_DEVELOPER, + ); } - - $tableheaders = array(get_string('template', 'feedback'), ''); + parent::__construct($uniqueid); + $this->cmid = $baseurl->param('id'); + $tablecolumns = [ + 'template' => get_string('template', 'feedback'), + 'actions' => '', + ]; $this->set_attribute('class', 'templateslist'); - $this->define_columns($tablecolumns); - $this->define_headers($tableheaders); + $this->define_columns(array_keys($tablecolumns)); + $this->define_headers(array_values($tablecolumns)); $this->define_baseurl($baseurl); $this->column_class('template', 'template'); $this->column_class('actions', 'text-end'); @@ -72,37 +82,82 @@ public function __construct($uniqueid, $baseurl, ?string $mode = null) { public function display($templates) { global $OUTPUT; if (empty($templates)) { - echo $OUTPUT->box(get_string('no_templates_available_yet', 'feedback'), - 'generalbox boxaligncenter'); + echo $OUTPUT->notification(get_string('no_templates_available_yet', 'feedback'), notification::NOTIFY_INFO, false); return; } $this->setup(); - $strdeletefeedback = get_string('delete_template', 'feedback'); foreach ($templates as $template) { - $data = []; - $url = new moodle_url($this->baseurl, array('templateid' => $template->id, 'sesskey' => sesskey())); - $data[] = $OUTPUT->action_link($url, format_string($template->name)); - - // Only show the actions if we are managing templates. - if ($this->mode && has_capability('mod/feedback:deletetemplate', $this->get_context())) { - $deleteurl = new moodle_url('/mod/feedback/manage_templates.php', - $url->params() + ['deletetemplate' => $template->id]); - $deleteaction = new confirm_action(get_string('confirmdeletetemplate', 'feedback')); - $deleteicon = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', $strdeletefeedback), $deleteaction); - if ($template->ispublic) { - $systemcontext = context_system::instance(); - if (!(has_capability('mod/feedback:createpublictemplate', $systemcontext) && - has_capability('mod/feedback:deletetemplate', $systemcontext))) { - $deleteicon = false; - } - } - $data[] = $deleteicon; - } + $showactions = has_any_capability( + ['mod/feedback:deletetemplate', 'mod/feedback:edititems', 'mod/feedback:createpublictemplate'], + $this->get_context() + ); + $data = [ + format_string($template->name), + $showactions ? $OUTPUT->render($this->get_row_actions($template)) : '', + ]; $this->add_data($data); } $this->finish_output(); } + + /** + * Get the row actions for the given template + * + * @param stdClass $template + * @return action_menu + */ + private function get_row_actions(stdClass $template) { + global $PAGE, $OUTPUT; + + $url = new moodle_url($this->baseurl, array('templateid' => $template->id, 'sesskey' => sesskey())); + $strdeletefeedback = get_string('delete_template', 'feedback'); + $actions = new action_menu(); + $actions->set_menu_trigger($OUTPUT->pix_icon('a/setting', get_string('actions'))); + + // Preview. + $actions->add(new link_secondary( + new moodle_url($this->baseurl, array('templateid' => $template->id, 'sesskey' => sesskey())), + new pix_icon('t/preview', get_string('preview')), + get_string('preview'), + )); + + // Use template. + if (has_capability('mod/feedback:edititems', context_module::instance($this->cmid))) { + $PAGE->requires->js_call_amd('mod_feedback/usetemplate', 'init'); + $actions->add(new link_secondary( + new moodle_url('#'), + new pix_icon('i/files', get_string('preview')), + get_string('use_this_template', 'mod_feedback'), + ['data-action' => 'usetemplate', 'data-dataid' => $this->cmid, 'data-templateid' => $template->id], + )); + } + + // Delete. + $showdelete = has_capability('mod/feedback:deletetemplate', context_module::instance($this->cmid)); + if ($template->ispublic) { + $showdelete = has_all_capabilities( + ['mod/feedback:createpublictemplate', 'mod/feedback:deletetemplate'], + context_system::instance() + ); + } + if ($showdelete) { + $exporturl = new moodle_url( + '/mod/feedback/manage_templates.php', + $url->params() + ['deletetemplate' => $template->id] + ); + $deleteaction = new action_link( + $exporturl, + get_string('delete'), + new confirm_action(get_string('confirmdeletetemplate', 'feedback')), + ['class' => 'text-danger'], + new pix_icon('t/delete', $strdeletefeedback), + ); + $actions->add_secondary_action($deleteaction); + } + + return $actions; + } } diff --git a/mod/feedback/lang/en/feedback.php b/mod/feedback/lang/en/feedback.php index 96aaeef12a8bb..f4d3e83e620d4 100644 --- a/mod/feedback/lang/en/feedback.php +++ b/mod/feedback/lang/en/feedback.php @@ -33,9 +33,10 @@ $string['anonymous_entries'] = 'Anonymous entries ({$a})'; $string['anonymous_user'] = 'Anonymous user'; $string['answerquestions'] = 'Answer the questions'; -$string['append_new_items'] = 'Append new items'; +$string['append_new_items'] = 'Keep existing questions and add new questions at the end'; $string['autonumbering'] = 'Auto number questions'; $string['autonumbering_help'] = 'Enables or disables automated numbers for each question'; +$string['availableforallcourses'] = 'Available for all courses'; $string['average'] = 'Average'; $string['bold'] = 'Bold'; $string['calendarend'] = '{$a} closes'; @@ -60,10 +61,11 @@ $string['continue_the_form'] = 'Continue answering the questions'; $string['count_of_nums'] = 'Count of numbers'; $string['courseid'] = 'Course ID'; +$string['coursetemplates'] = 'Course templates'; $string['creating_templates'] = 'Save these questions as a new template'; $string['delete_entry'] = 'Delete entry'; $string['delete_item'] = 'Delete question'; -$string['delete_old_items'] = 'Delete old items'; +$string['delete_old_items'] = 'Override existing questions'; $string['delete_pagebreak'] = 'Delete page break'; $string['delete_template'] = 'Delete template'; $string['delete_templates'] = 'Delete template...'; @@ -233,6 +235,7 @@ $string['position'] = 'Position'; $string['previous_page'] = 'Previous page'; $string['previewquestions'] = 'Preview questions'; +$string['previewtemplate'] = 'Previewing \'{$a}\' template'; $string['privacy:metadata:completed'] = 'A record of the submissions to the feedback'; $string['privacy:metadata:completed:anonymousresponse'] = 'Whether the submission is to be used anonymously.'; $string['privacy:metadata:completed:timemodified'] = 'The time when the submission was last modified.'; @@ -257,7 +260,7 @@ $string['responses'] = 'Responses'; $string['responsetime'] = 'Responses time'; $string['save_as_new_item'] = 'Save as new question'; -$string['save_as_new_template'] = 'Save as new template'; +$string['save_as_new_template'] = 'Save as template'; $string['save_entries'] = 'Submit your answers'; $string['save_item'] = 'Save question'; $string['saving_failed'] = 'Saving failed'; @@ -274,6 +277,7 @@ $string['show_entry'] = 'Show response'; $string['show_nonrespondents'] = 'Show non-respondents'; $string['site_after_submit'] = 'Site after submit'; +$string['sitetemplates'] = 'Site templates'; $string['sort_by_course'] = 'Sort by course'; $string['started'] = 'Started'; $string['startedon'] = 'Started on {$a}'; @@ -297,7 +301,7 @@ $string['url_for_continue'] = 'Link to next activity'; $string['url_for_continue_help'] = 'After submitting the feedback, a continue button is displayed, which links to the course page. Alternatively, it may link to the next activity if the URL of the activity is entered here.'; $string['use_one_line_for_each_value'] = 'Use one line for each answer!'; -$string['use_this_template'] = 'Use this template'; +$string['use_this_template'] = 'Use template'; $string['using_templates'] = 'Use a template'; $string['vertical'] = 'Vertical'; -$string['whatfor'] = 'What do you want to do?'; +$string['whatfor'] = 'How would you like to apply the template?'; diff --git a/mod/feedback/lib.php b/mod/feedback/lib.php index de615fa79ff41..f8904ce23ebd7 100644 --- a/mod/feedback/lib.php +++ b/mod/feedback/lib.php @@ -2810,7 +2810,7 @@ function feedback_extend_settings_navigation(settings_navigation $settings, navi navigation_node::TYPE_CUSTOM, null, 'questionnode'); $feedbacknode->add(get_string('templates', 'feedback'), - new moodle_url('/mod/feedback/manage_templates.php', ['id' => $settings->get_page()->cm->id, 'mode' => 'manage']), + new moodle_url('/mod/feedback/manage_templates.php', ['id' => $settings->get_page()->cm->id]), navigation_node::TYPE_CUSTOM, null, 'templatenode'); } diff --git a/mod/feedback/manage_templates.php b/mod/feedback/manage_templates.php index b7f8543f34125..2ae7a6aff4fc3 100644 --- a/mod/feedback/manage_templates.php +++ b/mod/feedback/manage_templates.php @@ -27,7 +27,6 @@ require_once("lib.php"); $id = required_param('id', PARAM_INT); -$mode = optional_param('mode', '', PARAM_ALPHA); $templateid = optional_param('deletetemplate', 0, PARAM_INT); list($course, $cm) = get_course_and_cm_from_cmid($id, 'feedback'); @@ -40,16 +39,13 @@ $systemcontext = context_system::instance(); $params = ['id' => $id]; -if ($mode) { - $params += ['mode' => $mode]; -} $url = new moodle_url('/mod/feedback/manage_templates.php', $params); $PAGE->set_url($url); -$actionbar = new \mod_feedback\output\edit_action_bar($cm->id, $url); $PAGE->set_heading($course->fullname); $PAGE->set_title($feedback->name); +$PAGE->add_body_class('limitedwidth'); // Process template deletion. if ($templateid) { @@ -73,25 +69,22 @@ echo $OUTPUT->header(); /** @var \mod_feedback\output\renderer $renderer */ $renderer = $PAGE->get_renderer('mod_feedback'); -if (!$mode) { - echo $renderer->main_action_bar($actionbar); -} echo $OUTPUT->heading(get_string('templates', 'mod_feedback'), 3); // First we get the course templates. $templates = feedback_get_template_list($course, 'own'); echo $OUTPUT->box_start('coursetemplates'); -echo $OUTPUT->heading(get_string('course'), 4); +echo $OUTPUT->heading(get_string('coursetemplates', 'mod_feedback'), 4); $baseurl = new moodle_url('/mod/feedback/use_templ.php', $params); -$tablecourse = new mod_feedback_templates_table('feedback_template_course_table', $baseurl, $mode); +$tablecourse = new mod_feedback_templates_table('feedback_template_course_table', $baseurl); $tablecourse->display($templates); echo $OUTPUT->box_end(); $templates = feedback_get_template_list($course, 'public'); echo $OUTPUT->box_start('publictemplates'); -echo $OUTPUT->heading(get_string('public', 'feedback'), 4); -$tablepublic = new mod_feedback_templates_table('feedback_template_public_table', $baseurl, $mode); +echo $OUTPUT->heading(get_string('sitetemplates', 'mod_feedback'), 4); +$tablepublic = new mod_feedback_templates_table('feedback_template_public_table', $baseurl); $tablepublic->display($templates); echo $OUTPUT->box_end(); echo $OUTPUT->footer(); diff --git a/mod/feedback/templates/main_action_menu.mustache b/mod/feedback/templates/main_action_menu.mustache index 8dc96b6aa694b..222531495adef 100644 --- a/mod/feedback/templates/main_action_menu.mustache +++ b/mod/feedback/templates/main_action_menu.mustache @@ -125,29 +125,6 @@ "helpicon": false } }, - "usetemplate": { - "id": 1, - "templateid": 2 - }, - "export": { - "disabled": false, - "url": "#", - "id": "test-id", - "classes": "btn btn-link", - "attributes": [ - { - "name": "title", - "value": "Action link's title" - } - ], - "icon": { - "attributes": [ - {"name": "src", "value": "https://raw.githubusercontent.com/moodle/moodle/master/pix/t/check.png"}, - {"name": "alt", "value": "Action link's icon"} - ] - }, - "text": "This is an action link" - } } }}
@@ -174,11 +151,6 @@ {{> core/action_menu }}
{{/addselect}} - {{#usetemplate }} - - {{/usetemplate}} {{#actionsselect}}