backbone dialog for lti content return

additionally added some denormalization to the external tools api
calls.  This explicitly defines properties for each extension that
are normally just inherited from the general extension settings.

test plan:
  -test a resource selection tool
  -test a homework submission tool
  -test a editor button tool
    * they should all still work

  - create a tool with selection_width, selection_height, and icon_url defaults
  - add a tool extension with no extra properties to this tool
  - make a get api call for the new external tool
    * it should have added the width, height, and icon to the extension

Change-Id: I25f7d31b5c4e21b1873d41e6ea4c39b4bd0e1a24
Reviewed-on: https://gerrit.instructure.com/21383
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Adam Phillipps <adam@instructure.com>
Reviewed-by: Bracken Mosbacker <bracken@instructure.com>
Product-Review: Bracken Mosbacker <bracken@instructure.com>
This commit is contained in:
Brad Humphrey 2013-06-05 16:56:53 -06:00
parent cd4f95e209
commit afa79ad601
9 changed files with 83 additions and 7 deletions

View File

@ -14,10 +14,13 @@ define [
# DiscussionTopicsCollection().fetch() it will go to
# /api/v1/courses/1/discussion_topics (since ENV.context_asset_string will
# be already set)
_defaultUrl: ->
_contextPath: ->
assetString = @contextAssetString || ENV.context_asset_string
[contextType, contextId] = splitAssetString assetString
"#{contextType}/#{contextId}"
_defaultUrl: ->
resourceName = @resourceName || @model::resourceName
throw new Error "Must define a `resourceName` property on collection or model prototype to use defaultUrl" unless resourceName
[contextType, contextId] = splitAssetString assetString
"/api/v1/#{contextType}/#{contextId}/#{resourceName}"
"/api/v1/#{@_contextPath()}/#{resourceName}"

View File

@ -19,3 +19,10 @@ define [
custom_field_string: ->
("#{k}=#{v}" for k,v of @get('custom_fields')).join("\n")
launchUrl: (launchType, options = {})->
params = for key, value of options
"#{key}=#{value}"
url = "/#{@_contextPath()}/external_tools/#{@id}/resource_selection?launch_type=#{launchType}"
url = "#{url}&#{params.join('&')}" if params.length > 0
url

View File

@ -0,0 +1,43 @@
define [
'jquery',
'jst/ExternalTools/ExternalContentReturnView'
], ($, template) ->
class ExternalContentReturnView extends Backbone.View
template: template
@optionProperty 'launchType'
@optionProperty 'launchParams'
els:
'iframe.tool_launch': "$iframe"
attach: ->
@model.on 'change', => @render()
$(window).one 'externalContentReady', @_contentReady
$(window).one 'externalContentCancel', @_contentCancel
toJSON: ->
json = super
json.launch_url = @model.launchUrl(@launchType, @launchParams)
json
afterRender: ->
#need to rework selection_height/width to be inclusive of cascading values
settings = @model.get(@launchType) || {}
@$iframe.width settings.selection_width
@$iframe.height settings.selection_height
@$el.dialog
title: 'Tool name'
width: settings.selection_width
height: settings.selection_height
resizable: true
close: =>
@remove()
_contentReady: (event, data) =>
@trigger 'ready', data
@remove()
_contentCancel: (event, data) =>
@trigger 'cancel', data
@remove()

View File

@ -285,7 +285,7 @@ class ExternalToolsController < ApplicationController
return unless authorized_action(@context, @current_user, :read)
add_crumb(@context.name, named_context_url(@context, :context_url))
selection_type = 'resource_selection'
selection_type = params[:launch_type] || 'resource_selection'
selection_type = 'editor_button' if params[:editor]
selection_type = 'homework_submission' if params[:homework]

View File

@ -11,6 +11,7 @@ while(parentWindow && !parentWindow[callback]) {
parentWindow = parentWindow.parent;
}
if(parentWindow[callback] && parentWindow[callback].cancel) {
parentWindow.$(parentWindow).trigger('externalContentCancel');
parentWindow[callback].cancel();
setTimeout(function() {
$("#dialog_message").text("<%= t :popup_success, "Canceled. This popup should close on its own..." %>");

View File

@ -16,6 +16,7 @@ require([
}
function dataReady(data) {
if(parentWindow[callback] && parentWindow[callback].ready) {
parentWindow.$(parentWindow).trigger('externalContentReady', data);
parentWindow[callback].ready(data);
setTimeout(function() {
$("#dialog_message").text("<%= t :popup_success, "Success! This popup should close on its own..." %>");

View File

@ -0,0 +1 @@
<iframe class="tool_launch" src="{{launch_url}}" frameborder="0"></iframe>

View File

@ -42,6 +42,11 @@ module Api::V1::ExternalTools
json[type]['label'] = tool.label_for(type, user.locale)
json[type].delete 'labels'
json.delete 'labels'
[:selection_width, :selection_height, :icon_url].each do |key|
value = tool.extension_setting type, key
json[type][key] = value if value
end
end
end

View File

@ -316,10 +316,25 @@ describe ExternalToolsController, :type => :integration do
"custom_fields"=>{"key1"=>"val1", "key2"=>"val2"},
"description"=>"For testing stuff",
"user_navigation"=>
{"text"=>"User nav", "url"=>"http://www.example.com/ims/lti/user", "label"=>"User nav"},
{"text"=>"User nav",
"url"=>"http://www.example.com/ims/lti/user",
"label"=>"User nav",
"selection_height"=>400,
"selection_width"=>800},
"course_navigation" =>
{"text"=>"Course nav", "url"=>"http://www.example.com/ims/lti/course", "visibility"=>"admins", "default"=> "disabled", "label"=>"Course nav"},
{"text"=>"Course nav",
"url"=>"http://www.example.com/ims/lti/course",
"visibility"=>"admins",
"default"=> "disabled",
"label"=>"Course nav",
"selection_height"=>400,
"selection_width"=>800},
"account_navigation"=>
{"text"=>"Account nav", "url"=>"http://www.example.com/ims/lti/account", "custom_fields"=>{"key"=>"value"}, "label"=>"Account nav"}}
{"text"=>"Account nav",
"url"=>"http://www.example.com/ims/lti/account",
"custom_fields"=>{"key"=>"value"},
"label"=>"Account nav",
"selection_height"=>400,
"selection_width"=>800}}
end
end