Improving the experience of instructor managed tool types

This commit is contained in:
Chris Scribner 2011-09-20 10:54:31 -04:00
parent 606ab1a13e
commit 16e8f13084
6 changed files with 98 additions and 36 deletions

View File

@ -20,6 +20,7 @@ switch($action){
if(!empty($tool)){ if(!empty($tool)){
$response->toolid = $tool->id; $response->toolid = $tool->id;
$response->toolname = htmlspecialchars($tool->name); $response->toolname = htmlspecialchars($tool->name);
$response->tooldomain = htmlspecialchars($tool->tooldomain);
} }
break; break;

View File

@ -34,10 +34,13 @@ if (confirm_sesskey() && isset($data->submitbutton)) {
lti_update_type($type, $data); lti_update_type($type, $data);
$fromdb = lti_get_type($typeid);
$json = json_encode($fromdb);
//Output script to update the calling window. //Output script to update the calling window.
$script = <<<SCRIPT $script = <<<SCRIPT
<script type="text/javascript"> <script type="text/javascript">
window.opener.M.mod_lti.editor.updateToolType({$name}, '{$typeid}'); window.opener.M.mod_lti.editor.updateToolType({$json});
window.close(); window.close();
</script> </script>
@ -51,12 +54,14 @@ SCRIPT;
$type->course = $COURSE->id; $type->course = $COURSE->id;
$id = lti_add_type($type, $data); $id = lti_add_type($type, $data);
$name = json_encode($type->name);
$fromdb = lti_get_type($id);
$json = json_encode($fromdb);
//Output script to update the calling window. //Output script to update the calling window.
$script = <<<SCRIPT $script = <<<SCRIPT
<script type="text/javascript"> <script type="text/javascript">
window.opener.M.mod_lti.editor.addToolType({$name}, '{$id}'); window.opener.M.mod_lti.editor.addToolType({$json});
window.close(); window.close();
</script> </script>

View File

@ -201,4 +201,9 @@ $string['delete_confirmation'] = 'Are you sure you want to delete this external
$string['cannot_edit'] = 'You may not edit this tool configuration.'; $string['cannot_edit'] = 'You may not edit this tool configuration.';
$string['cannot_delete'] = 'You may not delete this tool configuration.'; $string['cannot_delete'] = 'You may not delete this tool configuration.';
$string['global_tool_types'] = 'Global tool types'; $string['global_tool_types'] = 'Global tool types';
$string['course_tool_types'] = 'Course tool types'; $string['course_tool_types'] = 'Course tool types';
$string['using_tool_configuration'] = 'Using tool configuration: ';
$string['domain_mismatch'] = 'Launch URL\'s domain does not match tool configuration.';
$string['custom_config'] = 'Using custom tool configuration.';
$string['tool_config_not_found'] = 'Tool configuration not found for this URL.';

View File

@ -410,7 +410,7 @@ QUERY;
$types[0] = (object)array('name' => get_string('automatic', 'lti'), 'course' => $SITE->id); $types[0] = (object)array('name' => get_string('automatic', 'lti'), 'course' => $SITE->id);
foreach($admintypes as $type) { foreach($admintypes as $type) {
$types[$type->id] = (object)array('name' => $type->name, 'course' => $type->course); $types[$type->id] = $type;
} }
return $types; return $types;

View File

@ -1,6 +1,5 @@
(function(){ (function(){
var Y; var Y;
var self;
M.mod_lti = M.mod_lti || {}; M.mod_lti = M.mod_lti || {};
@ -10,7 +9,7 @@
Y = yui3; Y = yui3;
} }
self = this; var self = this;
this.settings = Y.JSON.parse(settings); this.settings = Y.JSON.parse(settings);
this.urlCache = {}; this.urlCache = {};
@ -47,7 +46,13 @@
self.updateAutomaticToolMatch(); self.updateAutomaticToolMatch();
}, },
clearToolCache: function(){
this.urlCache = {};
},
updateAutomaticToolMatch: function(){ updateAutomaticToolMatch: function(){
var self = this;
var toolurl = Y.one('#id_toolurl'); var toolurl = Y.one('#id_toolurl');
var typeSelector = Y.one('#id_typeid'); var typeSelector = Y.one('#id_typeid');
var automatchToolDisplay = Y.one('#lti_automatch_tool'); var automatchToolDisplay = Y.one('#lti_automatch_tool');
@ -62,8 +67,29 @@
var url = toolurl.get('value'); var url = toolurl.get('value');
if(!url || typeSelector.get('value') > 0){ //Hide the display if the url box is empty
if(!url){
automatchToolDisplay.setStyle('display', 'none'); automatchToolDisplay.setStyle('display', 'none');
} else {
automatchToolDisplay.set('innerHTML', '');
automatchToolDisplay.setStyle('display', '');
}
var selectedToolType = typeSelector.get('value');
var selectedOption = typeSelector.one('option[value=' + selectedToolType + ']');
//A specific tool type is selected (not "auto")"
if(selectedToolType > 0){
//If the entered domain matches the domain of the tool configuration...
var domainRegex = /(?:https?:\/\/)?(?:www\.)?([^\/]+)(?:\/|$)/i;
var match = domainRegex.exec(url);
if(match && match[1] && match[1].toLowerCase() === selectedOption.getAttribute('domain').toLowerCase()){
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.str.lti.using_tool_configuration + selectedOption.get('text'));
} else {
//The entered URL does not match the domain of the tool configuration
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.str.lti.domain_mismatch);
}
return; return;
} }
@ -72,17 +98,15 @@
//We don't care what tool type this tool is associated with if it's manually configured' //We don't care what tool type this tool is associated with if it's manually configured'
if(key.get('value') !== '' && secret.get('value') !== ''){ if(key.get('value') !== '' && secret.get('value') !== ''){
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />Using custom tool configuration.'); automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.str.lti.custom_config);
} else { } else {
var continuation = function(toolInfo){ var continuation = function(toolInfo){
automatchToolDisplay.setStyle('display', '');
if(toolInfo.toolname){ if(toolInfo.toolname){
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />Using tool configuration: ' + toolInfo.toolname); automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.str.lti.using_tool_configuration + toolInfo.toolname);
} else { } else {
//Inform them custom configuration is in use //Inform them custom configuration is in use
if(key.get('value') === '' || secret.get('value') === ''){ if(key.get('value') === '' || secret.get('value') === ''){
automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.yellow_check_icon_url + '" />Tool configuration not found for this URL.'); automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.str.lti.tool_config_not_found);
} }
} }
}; };
@ -147,6 +171,8 @@
* Javascript is a requirement to edit course level tools at this point. * Javascript is a requirement to edit course level tools at this point.
*/ */
createTypeEditorButtons: function(){ createTypeEditorButtons: function(){
var self = this;
var typeSelector = Y.one('#id_typeid'); var typeSelector = Y.one('#id_typeid');
var createIcon = function(id, tooltip, iconUrl){ var createIcon = function(id, tooltip, iconUrl){
@ -181,17 +207,7 @@
if(self.getSelectedToolTypeOption().getAttribute('editable')){ if(self.getSelectedToolTypeOption().getAttribute('editable')){
if(confirm(M.str.lti.delete_confirmation)){ if(confirm(M.str.lti.delete_confirmation)){
self.deleteTool(toolTypeId);
Y.io(self.settings.instructor_tool_type_edit_url + '&action=delete&typeid=' + toolTypeId, {
on: {
success: function(){
self.getSelectedToolTypeOption().remove();
},
failure: function(){
}
}
});
} }
} else { } else {
alert(M.str.lti.cannot_delete); alert(M.str.lti.cannot_delete);
@ -218,34 +234,65 @@
} }
}, },
addToolType: function(text, value){ addToolType: function(toolType){
var typeSelector = Y.one('#id_typeid'); var typeSelector = Y.one('#id_typeid');
var course_tool_group = Y.one('#course_tool_group'); var course_tool_group = Y.one('#course_tool_group');
var option = Y.Node.create('<option />') var option = Y.Node.create('<option />')
.set('text', text) .set('text', toolType.name)
.set('value', value) .set('value', toolType.id)
.set('selected', 'selected') .set('selected', 'selected')
.setAttribute('editable', '1') .setAttribute('editable', '1')
.setAttribute('courseTool', '1'); .setAttribute('courseTool', '1')
.setAttribute('domain', toolType.tooldomain);
if(course_tool_group){ if(course_tool_group){
course_tool_group.append(option); course_tool_group.append(option);
} else { } else {
typeSelector.append(option); typeSelector.append(option);
} }
//Adding the new tool may affect which tool gets matched automatically
this.clearToolCache();
this.updateAutomaticToolMatch();
}, },
updateToolType: function(text, value){ updateToolType: function(toolType){
var typeSelector = Y.one('#id_typeid'); var typeSelector = Y.one('#id_typeid');
var option = typeSelector.one('option[value=' + value + ']'); var option = typeSelector.one('option[value=' + toolType.id + ']');
option.set('text', text); option.set('text', toolType.name)
.set('domain', toolType.tooldomain);
//Editing the tool may affect which tool gets matched automatically
this.clearToolCache();
this.updateAutomaticToolMatch();
},
deleteTool: function(toolTypeId){
var self = this;
Y.io(self.settings.instructor_tool_type_edit_url + '&action=delete&typeid=' + toolTypeId, {
on: {
success: function(){
self.getSelectedToolTypeOption().remove();
//Editing the tool may affect which tool gets matched automatically
self.clearToolCache();
self.updateAutomaticToolMatch();
},
failure: function(){
}
}
});
}, },
findToolByUrl: function(url, callback){ findToolByUrl: function(url, callback){
var self = this;
Y.io(self.settings.ajax_url, { Y.io(self.settings.ajax_url, {
data: { action: 'find_tool_config', data: {action: 'find_tool_config',
course: self.settings.courseId, course: self.settings.courseId,
toolurl: url toolurl: url
}, },

View File

@ -80,9 +80,9 @@ class mod_lti_mod_form extends moodleform_mod {
foreach(lti_get_types_for_add_instance() as $id => $type){ foreach(lti_get_types_for_add_instance() as $id => $type){
if($type->course == $COURSE->id) { if($type->course == $COURSE->id) {
$attributes = array( 'editable' => 1, 'courseTool' => 1 ); $attributes = array( 'editable' => 1, 'courseTool' => 1, 'domain' => $type->tooldomain );
} else if($id != 0) { } else if($id != 0) {
$attributes = array( 'globalTool' => 1); $attributes = array( 'globalTool' => 1, 'domain' => $type->tooldomain);
} else { } else {
$attributes = array(); $attributes = array();
} }
@ -169,7 +169,7 @@ class mod_lti_mod_form extends moodleform_mod {
'add_icon_url' => (string)$OUTPUT->pix_url('t/add'), 'add_icon_url' => (string)$OUTPUT->pix_url('t/add'),
'delete_icon_url' => (string)$OUTPUT->pix_url('t/delete'), 'delete_icon_url' => (string)$OUTPUT->pix_url('t/delete'),
'green_check_icon_url' => (string)$OUTPUT->pix_url('i/tick_green_small'), 'green_check_icon_url' => (string)$OUTPUT->pix_url('i/tick_green_small'),
'yellow_check_icon_url' => (string)$OUTPUT->pix_url('i/tick_amber_small'), 'warning_icon_url' => (string)$OUTPUT->pix_url('warning', 'lti'),
'instructor_tool_type_edit_url' => $editurl->out(false), 'instructor_tool_type_edit_url' => $editurl->out(false),
'ajax_url' => $ajaxurl->out(true), 'ajax_url' => $ajaxurl->out(true),
'courseId' => $COURSE->id 'courseId' => $COURSE->id
@ -187,7 +187,11 @@ class mod_lti_mod_form extends moodleform_mod {
array('cannot_edit', 'lti'), array('cannot_edit', 'lti'),
array('cannot_delete', 'lti'), array('cannot_delete', 'lti'),
array('global_tool_types', 'lti'), array('global_tool_types', 'lti'),
array('course_tool_types', 'lti') array('course_tool_types', 'lti'),
array('using_tool_configuration', 'lti'),
array('domain_mismatch', 'lti'),
array('custom_config', 'lti'),
array('tool_config_not_found', 'lti')
), ),
); );