Commit 773051b9 authored by Peter Dias's avatar Peter Dias
Browse files

MDL-71914 mod_feedback: Add tertiary nav in feedback

parent 10b7badd
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
// 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/>.
/**
* Javascript module for saving a new template.
*
* @module mod_feedback/createtemplate
* @copyright 2021 Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalForm from 'core_form/modalform';
import Notification from 'core/notification';
import {get_string as getString} from 'core/str';
import {add as addToast} from 'core/toast';
const selectors = {
modaltrigger: '[data-action="createtemplate"]',
};
/**
* Initialize module
*/
export const init = () => {
const trigger = document.querySelector(selectors.modaltrigger);
trigger.addEventListener('click', event => {
event.preventDefault();
const ele = event.currentTarget;
const modalForm = new ModalForm({
modalConfig: {
title: getString('save_as_new_template', 'mod_feedback'),
},
formClass: 'mod_feedback\\form\\create_template_form',
args: {
id: ele.dataset.dataid
},
saveButtonText: getString('save', 'core')
});
// Show a toast notification when the form is submitted.
modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {
if (event.detail.result) {
getString('template_saved', 'feedback').then(addToast).catch();
} else {
getString('saving_failed', 'feedback').then(string => {
return Notification.addNotification({
type: 'error',
message: string
});
}).catch();
}
});
modalForm.show();
});
};
// 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/>.
/**
* Javascript module for using an existing template
*
* @module mod_feedback/usetemplate
* @copyright 2021 Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalForm from 'core_form/modalform';
import Notification from 'core/notification';
import {get_string as getString} from 'core/str';
const selectors = {
modaltrigger: '[data-action="usetemplate"]',
};
/**
* Initialize module
*/
export const init = () => {
const trigger = document.querySelector(selectors.modaltrigger);
trigger.addEventListener('click', event => {
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')
});
// 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();
});
};
...@@ -49,11 +49,9 @@ if (!$feedbackstructure->can_view_analysis()) { ...@@ -49,11 +49,9 @@ if (!$feedbackstructure->can_view_analysis()) {
$PAGE->set_heading($course->fullname); $PAGE->set_heading($course->fullname);
$PAGE->set_title($feedback->name); $PAGE->set_title($feedback->name);
echo $OUTPUT->header(); echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($feedback->name)); if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($feedback->name));
/// print the tabs }
require('tabs.php');
//get the groupid //get the groupid
$mygroupid = groups_get_activity_group($cm, true); $mygroupid = groups_get_activity_group($cm, true);
......
...@@ -71,10 +71,9 @@ $strfeedback = get_string("modulename", "feedback"); ...@@ -71,10 +71,9 @@ $strfeedback = get_string("modulename", "feedback");
$PAGE->set_heading($course->fullname); $PAGE->set_heading($course->fullname);
$PAGE->set_title($feedback->name); $PAGE->set_title($feedback->name);
echo $OUTPUT->header(); echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($feedback->name)); if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($feedback->name));
/// print the tabs }
require('tabs.php');
//get the groupid //get the groupid
//lstgroupid is the choosen id //lstgroupid is the choosen id
......
...@@ -713,7 +713,7 @@ class mod_feedback_completion extends mod_feedback_structure { ...@@ -713,7 +713,7 @@ class mod_feedback_completion extends mod_feedback_structure {
if ($this->form->is_cancelled()) { if ($this->form->is_cancelled()) {
// Form was cancelled - return to the course page. // Form was cancelled - return to the course page.
$urltogo = course_get_url($this->courseid ?: $this->feedback->course); $urltogo = new moodle_url('/mod/feedback/view.php', ['id' => $this->get_cm()->id]);
} else if ($this->form->is_submitted() && } else if ($this->form->is_submitted() &&
($this->form->is_validated() || $gopreviouspage)) { ($this->form->is_validated() || $gopreviouspage)) {
// Form was submitted (skip validation for "Previous page" button). // Form was submitted (skip validation for "Previous page" button).
......
<?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/>.
namespace mod_feedback\form;
use core_form\dynamic_form;
use moodle_url;
use context;
use context_module;
use context_system;
/**
* Prints the create new template form
*
* @copyright 2021 Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package mod_feedback
*/
class create_template_form extends dynamic_form {
/**
* Define the form
*/
public function definition() {
$mform =& $this->_form;
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('text',
'templatename',
get_string('name', 'feedback'),
['maxlength' => '200', 'size' => '50']);
$mform->setType('templatename', PARAM_TEXT);
if (has_capability('mod/feedback:createpublictemplate', context_system::instance())) {
$mform->addElement('checkbox',
'ispublic', '',
get_string('public', 'feedback'));
}
}
/**
* Returns context where this form is used
*
* @return context
*/
protected function get_context_for_dynamic_submission(): context {
$id = $this->optional_param('id', null, PARAM_INT);
list($course, $cm) = get_course_and_cm_from_cmid($id, 'feedback');
return context_module::instance($cm->id);
}
/**
* Checks if current user has access to this form, otherwise throws exception
*
* @throws \moodle_exception User does not have capability to access the form
*/
protected function check_access_for_dynamic_submission(): void {
$context = $this->get_context_for_dynamic_submission();
if (!has_capability('mod/feedback:edititems', $context) ||
!(has_capability('mod/feedback:createprivatetemplate', $context) ||
has_capability('mod/feedback:createpublictemplate', $context))) {
throw new \moodle_exception('nocapabilitytousethisservice');
}
}
/**
* Process the form submission, used if form was submitted via AJAX
*
* @return array Returns whether a new template was created.
*/
public function process_dynamic_submission(): array {
global $PAGE;
$formdata = $this->get_data();
$ispublic = !empty($formdata->ispublic) ? 1 : 0;
$result = feedback_save_as_template($PAGE->activityrecord, $formdata->templatename, $ispublic);
return [
'result' => $result,
];
}
/**
* Load in existing data as form defaults
*/
public function set_data_for_dynamic_submission(): void {
$this->set_data((object)[
'id' => $this->optional_param('id', null, PARAM_INT),
]);
}
/**
* Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX
*
* @return moodle_url
*/
protected function get_page_url_for_dynamic_submission(): moodle_url {
$params = [
'id' => $this->optional_param('id', null, PARAM_INT),
];
return new moodle_url('/mod/feedback/edit.php', $params);
}
}
<?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/>.
namespace mod_feedback\form;
use core_form\dynamic_form;
use moodle_url;
use context;
use context_module;
/**
* Prints the confirm use template form
*
* @copyright 2021 Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package mod_feedback
*/
class use_template_form extends dynamic_form {
/**
* Define the form
*/
public function definition() {
$mform =& $this->_form;
$mform->addElement('static', 'generalheader', '', get_string("whatfor", 'feedback'));
$mform->addElement('radio', 'deleteolditems', '', get_string('delete_old_items', 'feedback'), 1);
$mform->addElement('radio', 'deleteolditems', '', get_string('append_new_items', 'feedback'), 0);
$mform->setType('deleteolditems', PARAM_INT);
$mform->setDefault('deleteolditems', 1);
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'templateid');
$mform->setType('templateid', PARAM_INT);
}
/**
* Returns context where this form is used
*
* @return context
*/
protected function get_context_for_dynamic_submission(): context {
$id = $this->optional_param('id', null, PARAM_INT);
list($course, $cm) = get_course_and_cm_from_cmid($id, 'feedback');
return context_module::instance($cm->id);
}
/**
* Checks if current user has access to this form, otherwise throws exception
*
* @throws \moodle_exception User does not have capability to access the form
*/
protected function check_access_for_dynamic_submission(): void {
if (!has_capability('mod/feedback:edititems', $this->get_context_for_dynamic_submission())) {
throw new \moodle_exception('nocapabilitytousethisservice');
}
}
/**
* Process the form submission, used if form was submitted via AJAX
*
* @return array Returns the following information
* - the template was successfully created/updated from the provided template
* - the redirect url.
*/
public function process_dynamic_submission(): array {
global $PAGE;
$formdata = $this->get_data();
$templateid = $this->optional_param('templateid', null, PARAM_INT);
$id = $this->optional_param('id', null, PARAM_INT);
$response = feedback_items_from_template($PAGE->activityrecord, $templateid, $formdata->deleteolditems);
$url = new moodle_url('/mod/feedback/edit.php', ['id' => $id]);
if ($response !== false) {
// Provide a notification on success as the user will be redirected.
\core\notification::add(get_string('feedbackupdated', 'feedback'), \core\notification::SUCCESS);
}
return [
'result' => $response !== false,
'url' => $url->out()
];
}
/**
* Load in existing data as form defaults
*/
public function set_data_for_dynamic_submission(): void {
$this->set_data((object)[
'id' => $this->optional_param('id', null, PARAM_INT),
'templateid' => $this->optional_param('templateid', null, PARAM_INT)
]);
}
/**
* Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX
*
* @return moodle_url
*/
protected function get_page_url_for_dynamic_submission(): moodle_url {
$params = [
'id' => $this->optional_param('id', null, PARAM_INT),
'templateid' => $this->optional_param('templateid', null, PARAM_INT)
];
return new moodle_url('/mod/feedback/use_templ.php', $params);
}
}
<?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/>.
namespace mod_feedback\local\views;
use core\navigation\views\secondary as core_secondary;
/**
* Custom secondary navigation class
*
* A custom construct of secondary nav for feedback. This rearranges the nodes for the secondary
*
* @package mod_feedback
* @category navigation
* @copyright 2021 onwards Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class secondary extends core_secondary {
protected function get_default_module_mapping(): array {
$basenodes = parent::get_default_module_mapping();
$basenodes[self::TYPE_CUSTOM] += [
'templatenode' => 12,
'mapcourse' => 13,
'feedbackanalysis' => 14,
'responses' => 15,
'nonrespondents' => 15.1
];
return $basenodes;
}
/**
* Custom module construct for feedback
*/
protected function load_module_navigation(): void {
$settingsnav = $this->page->settingsnav;
$mainnode = $settingsnav->find('modulesettings', self::TYPE_SETTING);
$nodes = $this->get_default_module_mapping();
if ($mainnode) {
$url = new \moodle_url('/mod/' . $this->page->activityname . '/view.php', ['id' => $this->page->cm->id]);
$setactive = $url->compare($this->page->url, URL_MATCH_BASE);
$node = $this->add(get_string('modulename', 'feedback'), $url, null, null, 'modulepage');
if ($setactive) {
$node->make_active();
}
// Add the initial nodes.
$nodesordered = $this->get_leaf_nodes($mainnode, $nodes);
$this->add_ordered_nodes($nodesordered);
// Reorder the existing nodes in settings so the active node scan can pick it up.
$existingnode = $settingsnav->find('questionnode', self::TYPE_CUSTOM);
if ($existingnode) {
$node->add_node($existingnode);
$nodes[self::TYPE_CUSTOM] += ['questionnode' => 3];
}
// We have finished inserting the initial structure.
// Populate the menu with the rest of the nodes available.
$this->load_remaining_nodes($mainnode, $nodes);
}
}
}
<?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/>.
namespace mod_feedback\output;
use context_module;
use renderable;
use renderer_base;
use templatable;
/**
* Class base_action_bar
*
* Base class to be inherited by any other feedback action bar
*
* @package mod_feedback
* @copyright 2021 onwards Peter Dias
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class base_action_bar implements renderable, templatable {
/** @var int $cmid The module id */
protected $cmid;
/** @var object $context The context we are in */
protected $context;
/** @var object $course The course we are in */
protected $course;
/** @var array $urlparams The default params to be used when creating urls */
protected $urlparams;
/** @var object $feedback The activity record that is being viewed */
protected $feedback;
/**
* base_action_bar constructor.
*
* @param int $cmid
*/
public function __construct(int $cmid) {
global $PAGE;
$this->cmid = $cmid;
$this->context = context_module::instance($cmid);
[$course, $cm] = get_course_and_cm_from_cmid($cmid);
$this->course = $course;
$this->urlparams = [
'id' => $cmid
];
$this->feedback = $PAGE->activityrecord;
}
/**
* Recursively iterates through to array of renderables and exports
*
* @param array $items Collection of renderables
* @param renderer_base $output
* @return array $items Data to be used in the mustache template
*/
private function export_items_for_template(array $items, renderer_base $output): array {
$items = array_map(function($item) use ($output) {
if (is_array($item)) {
return $this->export_items_for_template($item, $output);
}
if (is_object($item) && method_exists($item, 'export_for_template')) {
return $item->export_for_template($output);
}
return $item;
}, $items);
return $items;
}
/**
* Export the data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return array
*/
public function export_for_template(renderer_base $output): array {
$items = $this->export_items_for_template($this->get_items(), $output);
return $items;
}
/**
* Function to generate a list of renderables to be displayed