Skip to content

Commit 15b2929

Browse files
committed
google docs front end
FIXES #CNVS-3196 this is the javascript bit that takes duanes refactored server side for the google docs submission and makes use of the new endpoint to lazy-load the google docs into it's tab when clicked. TEST PLAN: This should be a simple replacement of functionality (with the addition of an ajax loader) so regression tests on submitting google docs as assignment submissions are all that should be necessary. 1) login as a user who has authorized with google docs 2) go to the submission page for an assignment that allows a google doc submission 3) click the google docs tab, you should see a loader indicator and then the google docs tree. 4) pick a document, it should not allow you to pick more than one. 5) submit the document, it should give you a success message. Change-Id: Idd6c85668a40ef37a09631c635f3e83db69178e9 Reviewed-on: https://gerrit.instructure.com/17915 Reviewed-by: Brian Palmer <brianp@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> QA-Review: Clare Hetherington <clare@instructure.com>
1 parent 54f43dd commit 15b2929

10 files changed

Lines changed: 211 additions & 146 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
define ['i18n!titles', 'jquery', 'Backbone', 'jst/googleDocsTreeView'], (I18n, $, Backbone, template)->
2+
3+
class GoogleDocsTreeView extends Backbone.View
4+
5+
template: template
6+
7+
initialize: (options)->
8+
9+
events:
10+
"click li.file": "activateFile",
11+
"click li.folder": "activateFolder",
12+
13+
render: ()->
14+
title_text = I18n.t('view_in_separate_window', "View in Separate Window")
15+
16+
@$el.html @template({tree: @model, title_text: title_text})
17+
18+
@$el.instTree
19+
autoclose: false,
20+
multi: false,
21+
dragdrop: false
22+
23+
activateFile: (event)=>
24+
return if @$(event.target).closest(".popout").length > 0
25+
$target = @$(event.currentTarget)
26+
event.preventDefault()
27+
event.stopPropagation()
28+
@$(".file.active").removeClass 'active'
29+
$target.addClass 'active'
30+
file_id = $target.attr('id').substring(9)
31+
@trigger('activate-file', file_id)
32+
33+
activateFolder: (event)=>
34+
$target = @$(event.target)
35+
if $target.closest('.sign').length == 0 && $target.closest('.file,.folder').hasClass('folder')
36+
@$(event.currentTarget).find(".sign").click()
37+
38+
tagName: 'ul'
39+
40+
id: 'google_docs_tree'
41+
42+
attributes:
43+
style: 'width: 100%;'

app/controllers/assignments_controller.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,10 @@ def show
8787
@current_user_submission.send_later(:context_module_action) if @current_user_submission
8888
end
8989

90-
# prevent masquerading users from accessing google docs
91-
if @assignment.allow_google_docs_submission? && @real_current_user.blank?
92-
# TODO: make this happen asynchronously via ajax, and only if the user selects the google docs tab
93-
@google_docs = google_doc_list_deprecated(nil, @assignment.allowed_extensions) rescue nil
94-
end
90+
91+
begin
92+
@google_docs_token = google_docs_retrieve_access_token
93+
rescue RuntimeError => ex; end
9594

9695
add_crumb(@assignment.title, polymorphic_url([@context, @assignment]))
9796
log_asset_access(@assignment, "assignments", @assignment.assignment_group)
@@ -123,15 +122,19 @@ def list_google_docs
123122
ErrorReport.log_exception(:oauth, e)
124123
raise e
125124
end
126-
format.json { render :json => docs.to_hash }
125+
respond_to do |format|
126+
format.json { render :json => docs.to_hash }
127+
end
127128
else
128129
error_object = {:errors =>
129130
{:base => t('errors.google_docs_masquerade_rejected', "Unable to connect to Google Docs as a masqueraded user.")}
130131
}
131-
format.json { render :json => error_object.to_json, :status => :bad_request }
132+
respond_to do |format|
133+
format.json { render :json => error_object.to_json, :status => :bad_request }
134+
end
132135
end
133136
end
134-
137+
135138
def rubric
136139
@assignment = @context.assignments.active.find(params[:assignment_id])
137140
@root_outcome_group = outcome_group_json(@context.root_outcome_group, @current_user, session).to_json

app/views/assignments/_submit_assignment.html.erb

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -187,67 +187,48 @@
187187
}
188188
</style>
189189
<% if show_google_docs %>
190-
<% if @google_docs %>
190+
<% if @google_docs_token %>
191191
<% form_tag(context_url(@context, :controller => :submissions, :assignment_id => @assignment.id, :action => :create), {:id => "submit_google_doc_form", :class => "submit_assignment_form"}) do %>
192-
<%= hidden_field :submission, :submission_type, :value => "google_doc" %>
193-
<%= hidden_field :google_doc, :document_id, :value => "", :class => "google_doc_id" %>
194-
<table class="formtable" style="width: 100%;">
195-
<tr>
196-
<td style="padding-bottom: 10px;" colspan="2">
197-
<%= t 'instructions.google_docs', "Select the file from the list below." %>
198-
<%= render :partial => "assignments/group_submission_reminder" if @assignment.has_group_category? %>
192+
<%= hidden_field :submission, :submission_type, :value => "google_doc" %>
193+
<%= hidden_field :google_doc, :document_id, :value => "", :class => "google_doc_id" %>
194+
<table class="formtable" style="width: 100%;">
195+
<tr>
196+
<td style="padding-bottom: 10px;" colspan="2">
197+
<%= t 'instructions.google_docs', "Select the file from the list below." %>
198+
<%= render :partial => "assignments/group_submission_reminder" if @assignment.has_group_category? %>
199+
</td>
200+
</tr><tr>
201+
<td colspan="2">
202+
<div id="google_docs_container" style="height: 200px; overflow: auto;">
203+
<div style="text-align: center; margin: 10px;">
204+
<%= image_tag "ajax-loader-bar.gif" %>
205+
</div>
206+
</div>
199207
</td>
200-
</tr><tr>
201-
<td colspan="2">
202-
<div style="height: 200px; overflow: auto;">
203-
<ul id="google_docs_tree" style="width: 100%;">
204-
<% @google_docs.folders.each do |folder| %>
205-
<li class="folder"><%= folder %>
206-
<ul>
207-
<% @google_docs.files.select{|f| f.folder == folder}.each do |file| %>
208-
<li class="file <%= file.extension %>" id="document_<%= file.document_id %>">
209-
<span class="filename"><%= file.entry.title %></span>
210-
<a class="popout no-hover" href="<%= file.alternate_url %>" title="<%= t 'titles.view_in_separate_window', 'View in Separate Window' %>" target="_blank"><%= image_tag "popout.png " %></a>
211-
<div class="clear"></div>
212-
</li>
213-
<% end %>
214-
</ul>
215-
</li>
216-
<% end %>
217-
<% @google_docs.files.select{|f| f.folder == nil}.each do |file| %>
218-
<li class="file <%= file.extension %>" id="document_<%= file.document_id %>">
219-
<span class="filename"><%= file.entry.title %></span>
220-
<a class="popout no-hover" href="<%= file.alternate_url %>" target="_blank"><%= image_tag "popout.png " %></a>
221-
<div class="clear"></div>
222-
</li>
223-
<% end %>
224-
</ul>
225-
</div>
226-
</td>
227-
</tr><tr>
228-
<td colspan="2" style="text-align: center;">
229-
<div style="text-align: left;">
230-
<%= text_area :submission, :comment, :class => 'submission_comment_textarea', :placeholder => t('comments_placeholder', 'Comments...'), :title => t('additional_comments', 'Additional comments') %>
231-
</div>
232-
</td>
233-
</tr>
234-
<%= render :partial => "group_comment" %>
235-
<% if @assignment.turnitin_enabled? %>
236-
<%= render :partial => "turnitin" %>
237-
<% end %>
238-
<tr>
239-
<td colspan="2" class='button-container'>
240-
<button type="submit" class="btn"><%= t 'buttons.submit_assignment', "Submit Assignment" %></button>
241-
<button type="button" class='cancel_button button-secondary'><%= t '#buttons.cancel', "Cancel" %></button>
242-
</td>
243-
</tr>
244-
</table>
245-
<div id="uploading_google_doc_message" style="display: none;">
246-
<%= t 'messages.uploading', "Retrieving a copy of your Google Doc to submit for this assignment. This may take a little while, depending on the size of the file..." %>
247-
<div style="text-align: center; margin: 10px;">
248-
<%= image_tag "ajax-loader-bar.gif" %>
208+
</tr><tr>
209+
<td colspan="2" style="text-align: center;">
210+
<div style="text-align: left;">
211+
<%= text_area :submission, :comment, :class => 'submission_comment_textarea', :placeholder => t('comments_placeholder', 'Comments...'), :title => t('additional_comments', 'Additional comments') %>
212+
</div>
213+
</td>
214+
</tr>
215+
<%= render :partial => "group_comment" %>
216+
<% if @assignment.turnitin_enabled? %>
217+
<%= render :partial => "turnitin" %>
218+
<% end %>
219+
<tr>
220+
<td colspan="2" class='button-container'>
221+
<button type="submit" class="btn"><%= t 'buttons.submit_assignment', "Submit Assignment" %></button>
222+
<button type="button" class='cancel_button button-secondary'><%= t '#buttons.cancel', "Cancel" %></button>
223+
</td>
224+
</tr>
225+
</table>
226+
<div id="uploading_google_doc_message" style="display: none;">
227+
<%= t 'messages.uploading', "Retrieving a copy of your Google Doc to submit for this assignment. This may take a little while, depending on the size of the file..." %>
228+
<div style="text-align: center; margin: 10px;">
229+
<%= image_tag "ajax-loader-bar.gif" %>
230+
</div>
249231
</div>
250-
</div>
251232
<% end %>
252233
<% else %>
253234
<div id="submit_google_doc_form">
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{{#each tree.folders}}
2+
<li class="folder">
3+
{{name}}
4+
<ul>
5+
{{#each files}}
6+
<li class="file {{extension}}" id="document_{{document_id}}">
7+
<span class="filename">{{name}}</span>
8+
<a class="popout no-hover" href="{{alternate_url.href}}" title="{{../../title_text}}" target="_blank">
9+
<img src="/images/popout.png"/>
10+
</a>
11+
<div class="clear"></div>
12+
</li>
13+
{{/each}}
14+
</ul>
15+
</li>
16+
{{/each}}
17+
{{#each tree.top_level_files}}
18+
<li class="file {{extension}}" id="document_{{document_id}}">
19+
<span class="filename">{{name}}</span>
20+
<a class="popout no-hover" href="{{ alternate_url.href }}" title="{{../title_text}}" target="_blank">
21+
<img src='/images/popout.png'/>
22+
</a>
23+
<div class="clear"></div>
24+
</li>
25+
{{/each}}

config/routes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def add_zip_file_imports(context)
219219
course.old_calendar 'calendar', :controller => 'calendars', :action => 'show'
220220
course.locks 'locks', :controller => 'courses', :action => 'locks'
221221
add_discussions(course)
222-
course.resources :assignments, :collection => {:syllabus => :get, :submissions => :get}, :member => {:update_submission => :any} do |assignment|
222+
course.resources :assignments, :collection => {:syllabus => :get, :submissions => :get}, :member => {:list_google_docs => :get, :update_submission => :any} do |assignment|
223223
assignment.resources :submissions do |submission|
224224
submission.resubmit_to_turnitin 'turnitin/resubmit', :controller => 'submissions', :action => 'resubmit_to_turnitin', :conditions => {:method => :post}
225225
submission.turnitin_report 'turnitin/:asset_string', :controller => 'submissions', :action => 'turnitin_report'

lib/google_docs.rb

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def google_docs_request_token_url(return_to)
9494

9595
def google_docs_download(document_id)
9696
access_token = google_docs_retrieve_access_token
97-
entry = google_doc_list(access_token).files.find{|e| e.document_id == document_id}
97+
entry = google_doc_fetch_list(access_token).entries.map{|e| GoogleDocEntry.new(e) }.find{|e| e.document_id == document_id}
9898
if entry
9999
response = access_token.get(entry.download_url)
100100
response = access_token.get(response['Location']) if response.is_a?(Net::HTTPFound)
@@ -104,38 +104,6 @@ def google_docs_download(document_id)
104104
end
105105
end
106106

107-
# This can be removed as soon as our assignment submission page lazy loads
108-
# the list of google docs.
109-
def google_doc_list_deprecated(access_token = nil, only_extensions = nil)
110-
access_token ||= google_docs_retrieve_access_token
111-
response = access_token.get('https://docs.google.com/feeds/documents/private/full')
112-
docs = Atom::Feed.load_feed(response.body)
113-
folders, entries = [[], []]
114-
115-
docs.entries.each do |entry|
116-
folder = entry.categories.find do |category|
117-
category.scheme.match(%r{\Ahttp://schemas.google.com/docs/2007/folders})
118-
end
119-
120-
folders << folder.label if folder
121-
entries << GoogleDocEntry.new(entry)
122-
end
123-
124-
folders = folders.uniq.sort
125-
res = Struct.new(:files, :folders).new
126-
127-
if only_extensions.present?
128-
entries.reject! do |entry|
129-
!only_extensions.include?(entry.extension)
130-
end
131-
end
132-
133-
res.files = entries
134-
res.folders = folders
135-
136-
res
137-
end
138-
139107
class Folder
140108
attr_reader :name, :folders, :files
141109

0 commit comments

Comments
 (0)