From afa79ad601079978700602e4fb363982bb3f7e9e Mon Sep 17 00:00:00 2001 From: Brad Humphrey Date: Wed, 5 Jun 2013 16:56:53 -0600 Subject: [PATCH] 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 QA-Review: Adam Phillipps Reviewed-by: Bracken Mosbacker Product-Review: Bracken Mosbacker --- .../backbone-ext/DefaultUrlMixin.coffee | 9 ++-- app/coffeescripts/models/ExternalTool.coffee | 7 +++ .../ExternalContentReturnView.coffee | 43 +++++++++++++++++++ app/controllers/external_tools_controller.rb | 2 +- app/views/external_content/cancel.html.erb | 1 + app/views/external_content/success.html.erb | 1 + .../ExternalContentReturnView.handlebars | 1 + lib/api/v1/external_tools.rb | 5 +++ spec/apis/v1/external_tools_api_spec.rb | 21 +++++++-- 9 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 app/coffeescripts/views/ExternalTools/ExternalContentReturnView.coffee create mode 100644 app/views/jst/ExternalTools/ExternalContentReturnView.handlebars diff --git a/app/coffeescripts/backbone-ext/DefaultUrlMixin.coffee b/app/coffeescripts/backbone-ext/DefaultUrlMixin.coffee index d8a8abdb426..f462d6a0de0 100644 --- a/app/coffeescripts/backbone-ext/DefaultUrlMixin.coffee +++ b/app/coffeescripts/backbone-ext/DefaultUrlMixin.coffee @@ -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}" diff --git a/app/coffeescripts/models/ExternalTool.coffee b/app/coffeescripts/models/ExternalTool.coffee index 5a7cc6d0a46..09e90317616 100644 --- a/app/coffeescripts/models/ExternalTool.coffee +++ b/app/coffeescripts/models/ExternalTool.coffee @@ -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 diff --git a/app/coffeescripts/views/ExternalTools/ExternalContentReturnView.coffee b/app/coffeescripts/views/ExternalTools/ExternalContentReturnView.coffee new file mode 100644 index 00000000000..6cde19fc1f2 --- /dev/null +++ b/app/coffeescripts/views/ExternalTools/ExternalContentReturnView.coffee @@ -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() diff --git a/app/controllers/external_tools_controller.rb b/app/controllers/external_tools_controller.rb index 84b9ced7a51..9c4b1cf72b5 100644 --- a/app/controllers/external_tools_controller.rb +++ b/app/controllers/external_tools_controller.rb @@ -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] diff --git a/app/views/external_content/cancel.html.erb b/app/views/external_content/cancel.html.erb index deb95a5edc1..215ae0e3362 100644 --- a/app/views/external_content/cancel.html.erb +++ b/app/views/external_content/cancel.html.erb @@ -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..." %>"); diff --git a/app/views/external_content/success.html.erb b/app/views/external_content/success.html.erb index cc7feb35f79..7f704676bee 100644 --- a/app/views/external_content/success.html.erb +++ b/app/views/external_content/success.html.erb @@ -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..." %>"); diff --git a/app/views/jst/ExternalTools/ExternalContentReturnView.handlebars b/app/views/jst/ExternalTools/ExternalContentReturnView.handlebars new file mode 100644 index 00000000000..8b705c1cacc --- /dev/null +++ b/app/views/jst/ExternalTools/ExternalContentReturnView.handlebars @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/api/v1/external_tools.rb b/lib/api/v1/external_tools.rb index f1cebeabb4a..1c3f765c181 100644 --- a/lib/api/v1/external_tools.rb +++ b/lib/api/v1/external_tools.rb @@ -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 diff --git a/spec/apis/v1/external_tools_api_spec.rb b/spec/apis/v1/external_tools_api_spec.rb index 76cb3f1eb48..ae9953dce1e 100644 --- a/spec/apis/v1/external_tools_api_spec.rb +++ b/spec/apis/v1/external_tools_api_spec.rb @@ -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