MDL-78575 mod_lti: add course tools page to course

Uses a reportbuilder report to display course tools.
This commit is contained in:
Jake Dallimore 2023-06-29 17:34:21 +08:00
parent 348e347f79
commit a8f496e48e
No known key found for this signature in database
10 changed files with 711 additions and 0 deletions

View File

@ -0,0 +1,77 @@
<?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_lti\output;
use core_reportbuilder\system_report_factory;
use mod_lti\reportbuilder\local\systemreports\course_external_tools_list;
/**
* The course tools page renderable, containing a page header renderable and a course tools system report.
*
* @package mod_lti
* @copyright 2023 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_tools_page implements \renderable {
/** @var course_external_tools_list the course tools system report instance. */
protected course_external_tools_list $coursetoolsreport;
/** @var course_tools_page_header the page header renderable instance. */
protected course_tools_page_header $coursetoolspageheader;
/**
* Renderable constructor.
*
* @param int $courseid the id of the course.
*/
public function __construct(int $courseid) {
global $DB;
$context = \context_course::instance($courseid);
// Page intro, zero state and 'add new' button.
$canadd = has_capability('mod/lti:addcoursetool', $context);
$sql = 'SELECT COUNT(1)
FROM {lti_types} tt
WHERE tt.course IN(:siteid, :courseid)
AND tt.coursevisible NOT IN(:coursevisible)';
$toolcount = $DB->count_records_sql($sql, ['siteid' => get_site()->id, 'courseid' => $courseid, 'coursevisible' => 0]);
$this->coursetoolspageheader = new course_tools_page_header($courseid, $toolcount, $canadd);
// Course tools report itself.
$this->coursetoolsreport = system_report_factory::create(course_external_tools_list::class, $context);
}
/**
* Get the course tools page header renderable.
*
* @return course_tools_page_header the renderable.
*/
public function get_header(): course_tools_page_header {
return $this->coursetoolspageheader;
}
/**
* Get the course tools list system report.
*
* @return course_external_tools_list the course tools list report.
*/
public function get_table(): course_external_tools_list {
return $this->coursetoolsreport;
}
}

View File

@ -0,0 +1,62 @@
<?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_lti\output;
use core\output\notification;
use renderer_base;
/**
* Course tools page header renderable, containing the data for the page zero state and 'add tool' button.
*
* @package mod_lti
* @copyright 2023 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_tools_page_header implements \templatable {
/**
* Constructor.
*
* @param int $courseid the course id.
* @param int $toolcount the number of tools available in the course.
* @param bool $canadd whether the user can add tools to the course or not.
*/
public function __construct(protected int $courseid, protected int $toolcount, protected bool $canadd) {
}
/**
* Export the header's data for template use.
*
* @param renderer_base $output
* @return object the data.
*/
public function export_for_template(renderer_base $output): \stdClass {
$context = (object) [];
if ($this->canadd) {
$context->addlink = (new \moodle_url('/mod/lti/coursetooledit.php', ['course' => $this->courseid]))->out();
}
if ($this->toolcount == 0) {
$notification = new notification(get_string('nocourseexternaltoolsnotice', 'mod_lti'), notification::NOTIFY_INFO, true);
$context->notoolsnotice = $notification->export_for_template($output);
}
return $context;
}
}

View File

@ -84,4 +84,20 @@ class renderer extends plugin_renderer_base {
return parent::render_from_template('mod_lti/repost_crosssite', $data);
}
/**
* Render the course tools page header.
*
* @param course_tools_page $page the page renderable.
* @return string the rendered html for the page.
*/
protected function render_course_tools_page(course_tools_page $page): string {
// Render the table header templatable + the report.
$headerrenderable = $page->get_header();
$table = $page->get_table();
$headercontext = $headerrenderable->export_for_template($this);
$headeroutput = parent::render_from_template('mod_lti/course_tools_page_header', $headercontext);
return $headeroutput . $table->output();
}
}

View File

@ -0,0 +1,184 @@
<?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_lti\reportbuilder\local\entities;
use core_reportbuilder\local\filters\select;
use core_reportbuilder\local\filters\text;
use lang_string;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\report\column;
use core_reportbuilder\local\report\filter;
/**
* Course external tools entity class implementation.
*
* Defines all the columns and filters that can be added to reports that use this entity.
*
* @package mod_lti
* @copyright 2023 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_types extends base {
/**
* Database tables that this entity uses and their default aliases
*
* @return array
*/
protected function get_default_table_aliases(): array {
return ['lti_types' => 'tt', 'lti' => 'ti'];
}
/**
* The default title for this entity
*
* @return lang_string
*/
protected function get_default_entity_title(): lang_string {
return new lang_string('entitycourseexternaltools', 'mod_lti');
}
/**
* Initialize the entity
*
* @return base
*/
public function initialise(): base {
$columns = $this->get_all_columns();
foreach ($columns as $column) {
$this->add_column($column);
}
$filters = $this->get_all_filters();
foreach ($filters as $filter) {
$this->add_filter($filter);
}
return $this;
}
/**
* Returns list of all available columns
*
* @return column[]
*/
protected function get_all_columns(): array {
$tablealias = $this->get_table_alias('lti_types');
// Name column.
$columns[] = (new column(
'name',
new lang_string('name', 'core'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_fields("{$tablealias}.name, {$tablealias}.icon")
->set_is_sortable(true)
->add_callback(static function(string $name, \stdClass $data) {
global $OUTPUT;
$iconurl = $data->icon ?: $OUTPUT->image_url('monologo', 'lti')->out();
$iconclass = $data->icon ? ' nofilter' : '';
$iconcontainerclass = 'activityiconcontainer smaller content';
$name = $data->name;
$img = \html_writer::img($iconurl, get_string('courseexternaltooliconalt', 'mod_lti', $name),
['class' => 'activityicon' . $iconclass]);
$name = \html_writer::span($name, 'align-self-center');
return \html_writer::div(\html_writer::div($img, 'mr-2 '.$iconcontainerclass) . $name, 'd-flex');
});
// Description column.
$columns[] = (new column(
'description',
new lang_string('description', 'core'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$tablealias}.description")
->set_is_sortable(true);
// Course column.
$columns[] = (new column(
'course',
new lang_string('course', 'core'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_field("{$tablealias}.course")
->set_is_sortable(true);
// LTI Version column.
$columns[] = (new column(
'ltiversion',
new lang_string('version'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$tablealias}.ltiversion")
->set_is_sortable(true);
return $columns;
}
/**
* Return list of all available filters
*
* @return filter[]
*/
protected function get_all_filters(): array {
$tablealias = $this->get_table_alias('lti_types');
return [
// Name filter.
(new filter(
text::class,
'name',
new lang_string('name'),
$this->get_entity_name(),
"{$tablealias}.name"
))
->add_joins($this->get_joins()),
// Description filter.
(new filter(
text::class,
'description',
new lang_string('description'),
$this->get_entity_name(),
"{$tablealias}.description"
))
->add_joins($this->get_joins()),
// LTI Version filter.
(new filter(
select::class,
'ltiversion',
new lang_string('version'),
$this->get_entity_name(),
"{$tablealias}.ltiversion"
))
->add_joins($this->get_joins())
->set_options_callback(static function() : array {
return ['LTI-1p0' => 'Legacy LTI', '1.3.0' => "LTI Advantage"];
})
];
}
}

View File

@ -0,0 +1,192 @@
<?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_lti\reportbuilder\local\systemreports;
use core_reportbuilder\local\helpers\database;
use core_reportbuilder\local\report\column;
use mod_lti\reportbuilder\local\entities\tool_types;
use core_reportbuilder\system_report;
/**
* Course external tools list system report class implementation.
*
* @package mod_lti
* @copyright 2023 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_external_tools_list extends system_report {
/** @var \stdClass the course to constrain the report to. */
protected \stdClass $course;
/**
* Initialise report, we need to set the main table, load our entities and set columns/filters
*/
protected function initialise(): void {
global $DB;
$this->course = get_course($this->get_context()->instanceid);
// Our main entity, it contains all the column definitions that we need.
$entitymain = new tool_types();
$entitymainalias = $entitymain->get_table_alias('lti_types');
$this->set_main_table('lti_types', $entitymainalias);
$this->add_entity($entitymain);
// Now we can call our helper methods to add the content we want to include in the report.
$this->add_columns($entitymain);
$this->add_filters();
$this->add_actions();
// We need id and course in the actions, without entity prefixes, so add these here.
$this->add_base_fields("{$entitymainalias}.id, {$entitymainalias}.course");
// Scope the report to the course context only.
$paramprefix = database::generate_param_name();
$coursevisibleparam = database::generate_param_name();
[$insql, $params] = $DB->get_in_or_equal([get_site()->id, $this->course->id], SQL_PARAMS_NAMED, "{$paramprefix}_");
$wheresql = "{$entitymainalias}.course {$insql} AND {$entitymainalias}.coursevisible NOT IN (:{$coursevisibleparam})";
$params = array_merge($params, [$coursevisibleparam => 0]);
$this->add_base_condition_sql($wheresql, $params);
$this->set_downloadable(false, get_string('pluginname', 'mod_lti'));
$this->set_default_per_page(10);
$this->set_default_no_results_notice(null);
}
/**
* Validates access to view this report
*
* @return bool
*/
protected function can_view(): bool {
return has_capability('mod/lti:addpreconfiguredinstance', $this->get_context());
}
/**
* Adds the columns we want to display in the report.
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
* @param tool_types $tooltypesentity
* @return void
*/
protected function add_columns(tool_types $tooltypesentity): void {
$entitymainalias = $tooltypesentity->get_table_alias('lti_types');
$columns = [
'tool_types:name',
'tool_types:description',
];
$this->add_columns_from_entities($columns);
// Tool usage column using a custom SQL subquery to count tool instances within the course.
// TODO: This should be replaced with proper column aggregation once that's added to system_report instances in MDL-76392.
$ti = database::generate_param_name(); // Tool instance param.
$sql = "(SELECT count($ti.id) as usage
FROM {lti} $ti
WHERE $ti.typeid = {$entitymainalias}.id)";
$this->add_column(new column(
'usage',
new \lang_string('usage', 'mod_lti'),
$tooltypesentity->get_entity_name()
))
->set_type(column::TYPE_INTEGER)
->set_is_sortable(true)
->add_field($sql, 'usage');
// Attempt to create a dummy actions column, working around the limitations of the official actions feature.
$this->add_column(new column(
'actions', new \lang_string('actions'),
$tooltypesentity->get_entity_name()
))
->set_type(column::TYPE_TEXT)
->set_is_sortable(false)
->add_fields("{$entitymainalias}.id, {$entitymainalias}.course, {$entitymainalias}.name")
->add_callback(static function($field, $row) {
global $OUTPUT;
// Lock actions for site-level preconfigured tools.
if (get_site()->id == $row->course) {
return \html_writer::div(
\html_writer::div(
$OUTPUT->pix_icon('t/locked', get_string('sitetoolnocourseediting', 'mod_lti')
), 'tool-action-icon-container'), 'd-flex justify-content-end'
);
}
// Lock actions when the user can't add course tools.
if (!has_capability('mod/lti:addcoursetool', \context_course::instance($row->course))) {
return \html_writer::div(
\html_writer::div(
$OUTPUT->pix_icon('t/locked', get_string('courseexternaltoolsnoaddpermissions', 'mod_lti')
), 'tool-action-icon-container'), 'd-flex justify-content-end'
);
}
// 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.
$menu->add(new \action_menu_link(
new \moodle_url('/mod/lti/coursetooledit.php', ['course' => $row->course, 'typeid' => $row->id]),
null,
get_string('edit', 'core'),
null
));
$menu->add(new \action_menu_link(
new \moodle_url('#'),
null,
get_string('delete', 'core'),
null,
[
'data-action' => 'course-tool-delete',
'data-course-tool-id' => $row->id,
'data-course-tool-name' => $row->name
],
));
return $OUTPUT->render($menu);
});
// Default sorting.
$this->set_initial_sort_column('tool_types:name', SORT_ASC);
}
/**
* Add any actions for this report.
*
* @return void
*/
protected function add_actions(): void {
}
/**
* Adds the filters we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
protected function add_filters(): void {
$this->add_filters_from_entities([]);
}
}

62
mod/lti/coursetools.php Normal file
View File

@ -0,0 +1,62 @@
<?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/>.
/**
* Shows a tabulated view of all the available LTI tools in a given course.
*
* @package mod_lti
* @copyright 2023 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_lti\output\course_tools_page;
require_once("../../config.php");
require_once($CFG->dirroot . '/mod/lti/lib.php');
require_once($CFG->dirroot . '/mod/lti/locallib.php');
$id = required_param('id', PARAM_INT); // Course Id.
// Access + permissions.
$course = get_course($id);
require_course_login($course, false);
$context = context_course::instance($course->id);
if (!has_any_capability(['mod/lti:addpreconfiguredinstance', 'mod/lti:addcoursetool'], $context)) {
throw new \moodle_exception('nopermissions', 'error', '', get_string('courseexternaltoolsnoviewpermissions', 'mod_lti'));
}
// Page setup.
global $PAGE;
$pagetitle = get_string('courseexternaltools', 'mod_lti');
$pageurl = new moodle_url('/mod/lti/coursetools.php', ['id' => $course->id]);
$PAGE->set_pagelayout('incourse');
$PAGE->set_context($context);
$PAGE->set_url($pageurl);
$PAGE->set_title($pagetitle);
$PAGE->set_heading(format_string($course->fullname, true, ['context' => $context]));
$PAGE->add_body_class('limitedwidth');
// Display.
echo $OUTPUT->header();
echo $OUTPUT->heading($pagetitle);
$renderer = $PAGE->get_renderer('mod_lti');
$coursetoolspage = new course_tools_page($course->id);
echo $renderer->render($coursetoolspage);
$PAGE->requires->js_call_amd('mod_lti/course_tools_list', 'init');
echo $OUTPUT->footer();

View File

@ -70,6 +70,7 @@ $string['add_ltiadv'] = 'Add LTI Advantage';
$string['add_ltilegacy'] = 'Add Legacy LTI';
$string['addnewapp'] = 'Enable external application';
$string['addserver'] = 'Add new trusted server';
$string['addtool'] = 'Add tool';
$string['addtype'] = 'Add preconfigured tool';
$string['allow'] = 'Allow';
$string['allowsetting'] = 'Allow tool to store 8K of settings in Moodle';
@ -116,6 +117,11 @@ $string['contentitem_multiple_description'] = 'The following items will be added
$string['contentitem_multiple_graded'] = 'Graded activity (Maximum grade: {$a})';
$string['course_tool_types'] = 'Course tools';
$string['courseactivitiesorresources'] = 'Course activities or resources';
$string['courseexternaltooliconalt'] = 'Icon for the \'{$a}\' LTI External tool'; // TODO: confirm wording with UX.
$string['courseexternaltools'] = 'LTI External tools'; // TODO: confirm wording with UX.
$string['courseexternaltoolsinfo'] = 'LTI External tools are add-on apps you can integrate into your course, such as interactive content or assessments. Your students can access and use them without leaving your course.'; // TODO: confirm wording with UX.
$string['courseexternaltoolsnoaddpermissions'] = 'You don\'t have permission to add or edit course tools.'; // TODO: confirm wording with UX.
$string['courseexternaltoolsnoviewpermissions'] = 'View course external tools';
$string['courseid'] = 'Course ID number';
$string['courseinformation'] = 'Course information';
$string['courselink'] = 'Go to course';
@ -184,6 +190,7 @@ $string['enableemailnotification'] = 'Send notification emails';
$string['enableemailnotification_help'] = 'If enabled, students will receive email notification when their tool submissions are graded.';
$string['enterkeyandsecret'] = 'Enter your consumer key and shared secret';
$string['enterkeyandsecret_help'] = 'If you were given a consumer key and/or shared secret, input them here';
$string['entitycourseexternaltools'] = 'LTI External tools';
$string['errorbadurl'] = 'URL is not a valid tool URL or cartridge.';
$string['errorincorrectconsumerkey'] = 'Consumer key is incorrect.';
$string['errorinvaliddata'] = 'Invalid data: {$a}';
@ -339,6 +346,7 @@ $string['no_tp_configured'] = 'There are no unregistered external tool registrat
$string['no_tp_pending'] = 'There are no pending external tool registrations.';
$string['no_tp_rejected'] = 'There are no rejected external tool registrations.';
$string['noattempts'] = 'No attempts have been made on this tool instance';
$string['nocourseexternaltoolsnotice'] = 'There are no LTI external tools yet'; // TODO confirm wording with UX.
$string['noltis'] = 'There are no external tool instances';
$string['noprofileservice'] = 'Profile service not found';
$string['noservers'] = 'No servers found';
@ -507,6 +515,7 @@ $string['show_in_course_lti2_help'] = 'This tool can be shown in the activity ch
$string['show_in_course_no'] = 'Do not show; use only when a matching tool URL is entered';
$string['show_in_course_preconfigured'] = 'Show as preconfigured tool when adding an external tool';
$string['size'] = 'Size parameters';
$string['sitetoolnocourseediting'] = 'This is a site level tool which cannot be edited.'; // TODO: confirm wording with UX.
$string['opensslconfiginvalid'] = 'LTI 1.3 requires a valid openssl.cnf to be configured and available to your web server. Please contact the site administrator to configure and enable openssl for this site.';
$string['submission'] = 'Submission';
$string['submissions'] = 'Submissions';
@ -594,6 +603,7 @@ $string['unabletocreatetooltype'] = 'Unable to create tool';
$string['unabletofindtooltype'] = 'Unable to find tool for {$a->id}';
$string['unknownstate'] = 'Unknown state';
$string['update'] = 'Update';
$string['usage'] = 'Usage';
$string['useraccountinformation'] = 'User account information';
$string['userpersonalinformation'] = 'User personal information';
$string['using_tool_cartridge'] = 'Using tool cartridge';

View File

@ -765,3 +765,20 @@ function mod_lti_core_calendar_provide_event_action(calendar_event $event,
true
);
}
/**
* Extend the course navigation with an "LTI External tools" link which redirects to a list of all tools available for course use.
*
* @param settings_navigation $navigation The settings navigation object
* @param stdClass $course The course
* @param stdclass $context Course context
* @return void
*/
function mod_lti_extend_navigation_course($navigation, $course, $context): void {
if (has_any_capability(['mod/lti:addpreconfiguredinstance', 'mod/lti:addcoursetool'], $context)) {
$url = new moodle_url('/mod/lti/coursetools.php', ['id' => $course->id]);
$settingsnode = navigation_node::create(get_string('courseexternaltools', 'mod_lti'), $url, navigation_node::TYPE_SETTING,
null, 'coursetools', new pix_icon('i/settings', ''));
$navigation->add_node($settingsnode);
}
}

View File

@ -403,3 +403,38 @@
border: 1px solid #ddd;
border-radius: 4px;
}
img.coursetoolicon {
height: 24px;
width: 24px;
vertical-align: middle;
}
/* Strip the caret from the action menu toggle, as the ... ellipsis icon is used. */
#page-mod-lti-coursetools a.dropdown-toggle::after {
display: none;
}
/* Icons in the 'actions' column of the course tools table need to be aligned with action menus which have a 36x36 trigger. */
#page-mod-lti-coursetools table div.tool-action-icon-container {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
}
#page-mod-lti-coursetools table div.tool-action-icon-container i {
margin: 0;
}
/* The following removes the striping that lives in table_sql, which we can't change from within reportbuilder */
#page-mod-lti-coursetools table.generaltable tbody tr:nth-of-type(2n+1),
#page-mod-lti-coursetools table.table-striped tbody tr:nth-of-type(2n+1) {
background: inherit;
}
#page-mod-lti-coursetools table.generaltable tbody tr:hover,
#page-mod-lti-coursetools table.table-striped tbody tr:hover {
background: #fff;
}

View File

@ -0,0 +1,56 @@
{{!
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/>.
}}
{{!
@template mod_lti/course_tool_page_header
Contains the page header for the 'LTI External tools' course page.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* notoolsnotice Object exported notification, shown when the page has 0 tools available.
* addlink String link to the add tool type page.
Example context (json):
{
"notoolsnotice": {
"message": "There are no LTI External tools yet",
"extraclasses": "",
"announce": false,
"closebutton": true,
"isinfo": true
},
"addlink": "http://SITE/mod/lti/coursetooledit?course=45"
}
}}
<div>
<p>
{{#str}} courseexternaltoolsinfo, mod_lti {{/str}}
</p>
{{#notoolsnotice}}
{{> core/notification_info}}
{{/notoolsnotice}}
{{#addlink}}
<div class="mb-3">
<a class="btn btn-primary" href="{{{.}}}">{{#str}}addtool, mod_lti{{/str}}</a>
</div>
{{/addlink}}
</div>