show.mustache 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <%
  2. # Copyright (C) 2011 - present Instructure, Inc.
  3. #
  4. # This file is part of Canvas.
  5. #
  6. # Canvas is free software: you can redistribute it and/or modify it under
  7. # the terms of the GNU Affero General Public License as published by the Free
  8. # Software Foundation, version 3 of the License.
  9. #
  10. # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
  11. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. # details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License along
  16. # with this program. If not, see <http://www.gnu.org/licenses/>.
  17. %>
  18. <%
  19. currently_peer_reviewing = @assessment_request.try(:assigned?)
  20. js_bundle :submissions
  21. css_bundle :submission
  22. js_env({
  23. :RUBRIC_ASSESSMENT => {
  24. :assessment_user_id => @submission.user_id,
  25. :assessor_id => @current_user ? @current_user.id : "null",
  26. :assessment_type => (!currently_peer_reviewing && can_do(@submission, @current_user, :grade)) ? "grading" : "peer_review"
  27. },
  28. :SUBMISSION => {
  29. :user_id => @submission.user_id,
  30. :assignment_id => @assignment.id,
  31. # don't leak grades if assignment is muted
  32. :submission => @assignment.muted? ? {} : @submission.attributes.merge(entered_grade: @submission.entered_grade, entered_score: @submission.entered_score)
  33. }
  34. })
  35. content_for :page_title, join_title(@assignment.title, submission_author_name_for(@assessment_request))
  36. add_crumb(t('crumbs.assignments', "Assignments"), context_url(@context, :context_assignments_url))
  37. add_crumb(@assignment.title, context_url(@context, :context_assignment_url, @assignment.id))
  38. add_crumb(user_crumb_name)
  39. @active_tab = "assignments"
  40. %>
  41. <% content_for :stylesheets do %>
  42. <style>
  43. .rubric {
  44. max-width: 600px;
  45. }
  46. </style>
  47. <% end %>
  48. <% if @assignment.omit_from_final_grade %>
  49. <div class="alert alert-info omit-from-final-warning">
  50. This assignment does not count towards the final grade.
  51. </div>
  52. <% end %>
  53. <div class="submission-details-header submission_details">
  54. <div class="submission-details-header__grade-summary">
  55. <% if @assignment.muted? %>
  56. <p style="width: 200px">{{#t}}Grades are unavailable because the instructor is working on them.{{/t}}</p>
  57. <% elsif @submission.user_can_read_grade?(@current_user, session) %>
  58. <table class="grade-values">
  59. <tbody>
  60. <tr>
  61. <th><%= I18n.t('Grade:') %></td>
  62. <td class="bold">
  63. <% if can_do(@assignment, @current_user, :grade) %>
  64. {{> views/gradebooks/grading_box}}
  65. <% elsif @submission.user_can_read_grade?(@current_user, session) %>
  66. <span class="entered_grade">
  67. <% if @submission.excused? %>
  68. <%= t "Excused" %>
  69. <% else %>
  70. <%= i18n_grade(round_if_whole @submission.entered_grade) %>
  71. <% end %>
  72. </span>
  73. <% if !@submission.excused? && @assignment.grading_type == 'points' && @assignment.points_possible %>
  74. <%= t('/ %{points_possible}', points_possible: I18n.n(round_if_whole @assignment.points_possible))%>
  75. <% end %>
  76. <% end %>
  77. </td>
  78. </tr>
  79. <% if can_do(@assignment, @current_user, :grade) || @submission.user_can_read_grade?(@current_user, session)
  80. points_deducted = I18n.n(-@submission.points_deducted) if @submission.points_deducted&.> 0
  81. points_possible = I18n.n(round_if_whole(@assignment.points_possible))
  82. grade_breakdown_style = hidden unless points_deducted && !@submission.excused?
  83. %>
  84. <tr class="error late-penalty-display" style="<%= grade_breakdown_style %>">
  85. <th><%= I18n.t('Late penalty:') %></td>
  86. <td class="late_penalty bold"><%= points_deducted %></td>
  87. </tr>
  88. <tr class="late-penalty-display" style="<%= grade_breakdown_style %>">
  89. <th><%= I18n.t('Final grade:') %></td>
  90. <td class="bold">
  91. <% if can_do(@assignment, @current_user, :grade) %>
  92. <span class="published_grade"><%= i18n_grade(round_if_whole @submission.grade) %></span>
  93. <% elsif @submission.user_can_read_grade?(@current_user, session) %>
  94. <span class="grade"><%= i18n_grade(round_if_whole @submission.published_grade) %></span>
  95. <% end %>
  96. <% if @assignment.grading_type == 'points' %>
  97. / <%= points_possible %>
  98. <% end %>
  99. </td>
  100. </tr>
  101. <% end %>
  102. </tbody>
  103. </table>
  104. <% if can_do(@submission, @current_user, :view_turnitin_report) %>
  105. <% if (turnitin_score = @submission.turnitin_data[@submission.asset_string]) &&
  106. @submission.turnitin_data[:provider] == nil && turnitin_score[:similarity_score] %>
  107. <span class="turnitin_score_container">
  108. <span class="turnitin_score_container_caret <%= turnitin_score[:state] %>_score"></span>
  109. <a href="<%= context_url(@context, :context_assignment_submission_turnitin_report_url, @submission.assignment_id, @submission.user_id, @submission.asset_string) %>" target="_blank" class="not_external turnitin_similarity_score <%= turnitin_score[:state] %>_score"><%= turnitin_score[:similarity_score] %>%</a>
  110. </span>
  111. <% end %>
  112. <% end %>
  113. <% elsif @submission.can_view_plagiarism_report('vericite', @current_user, session) && !@assignment.muted? %>
  114. <% if (vericite_score = @submission.vericite_data(true)[@submission.asset_string]) && @submission.turnitin_data[:provider] == :vericite && vericite_score[:similarity_score] %>
  115. <span class="turnitin_score_container">
  116. <span class="vericite_score_container_caret <%= vericite_score[:state] %>_score"></span>
  117. <a href="<%= context_url(@context, :context_assignment_submission_vericite_report_url, @submission.assignment_id, @submission.user_id, @submission.asset_string) %>" target="_blank" title="Similarity score -- more information" class="tooltip not_external turnitin_similarity_score <%= vericite_score[:state] %>_score">
  118. <%= vericite_score[:similarity_score] %>%
  119. <span class="tooltip_wrap right">
  120. <span class="tooltip_text">{{#t}}See VeriCite results{{/t}}</span>
  121. </span>
  122. </a>
  123. </span>
  124. <% end %>
  125. <% end %>
  126. <% if @assignment.rubric_association && (
  127. @submission.user_can_read_grade?(@current_user, session) ||
  128. @assignment.rubric_association.user_can_assess_for?(assessor: @current_user, assessee: @submission.user) ||
  129. can_do(@assignment.rubric, @current_user, :read)
  130. )
  131. %>
  132. <a href="#" class="assess_submission_link Submission__Link--has-icon" style="font-size: 0.8em;" tabindex='0'>
  133. <i class="icon-rubric" aria-hidden="true"></i>
  134. {{#t}}Show Rubric{{/t}}
  135. </a>
  136. <% end %>
  137. </div>
  138. <h2 class="submission_header" style="margin-bottom: 0;"><%= @assessment_request ? t('peer_review', "Peer Review") : t('submission_details', "Submission Details") %></h2>
  139. <span class="SubmissionDetails__Text"><%= @assignment.title %>, <%= submission_author_name_for @assessment_request %></span>
  140. <span class="SubmissionDetails__Text <%='late' if @submission.late? %> <%= 'hidden' unless @submission.submitted_at %>">
  141. <%= t('submitted_at', 'submitted %{submit_date}', :submit_date => datetime_string(@submission.submitted_at)) %>
  142. </span>
  143. <% if @context.feature_enabled?(:new_gradebook) %>
  144. <% if @submission.late? %>
  145. <span class="submission-late-pill"></span>
  146. <% elsif @submission.missing? %>
  147. <span class="submission-missing-pill"></span>
  148. <% end %>
  149. <% end %>
  150. <% if can_do(@context, @current_user, :grade) %>
  151. <a class="forward" href="<%= context_url(@context, :speed_grader_context_gradebook_url, :assignment_id => @assignment.id) + "#" + CGI::escape({:student_id => @submission.user_id }.to_json) %>" style="float: right; padding-right: 10px;">{{#t}}SpeedGrader™{{/t}}</a>
  152. <% end %>
  153. <% if @assignment.expects_submission? && can_do(@assignment, @current_user, :submit) && @current_user == @submission.user %>
  154. <span><a href="<%= context_url(@context, :context_assignment_url, @assignment.id) %>#submit" class="Button Button--primary" >
  155. <%= @submission.has_submission? ? t('links.resubmit', "Re-submit Assignment") : t('links.submit', "Submit Assignment") %>
  156. </a></span>
  157. <% end %>
  158. <% if @assessment_request %>
  159. <div class="assessment_request_completed_message" style="<%= hidden unless @assessment_request.completed? %>">
  160. {{#t}}You have finished the required steps for this peer review.{{/t}}
  161. </div>
  162. <div class="assessment_request_incomplete_message" style="<%= hidden if @assessment_request.completed? %>">
  163. <% if @assessment_request && @assessment_request.rubric_association %>
  164. <%= mt('peer_review_not_done_rubric', "**This peer review is not finished yet.** For it to be considered finished, you need to leave at least one comment and fill out the rubric form to the right.")
  165. %>
  166. <% else %>
  167. <%= mt('peer_review_not_done', "**This peer review is not finished yet.** For it to be considered finished, you need to leave at least one comment.")
  168. %>
  169. <% end %>
  170. </div>
  171. <div>
  172. </div>
  173. <% end %>
  174. <div class="clear"></div>
  175. </div>
  176. <% if @assignment.rubric_association %>
  177. <% @visible_rubric_assessments ||= [] %>
  178. <div id="rubric_holder" style="position: absolute; right: 0px; padding: 5px; background-color: #fff; border: 1px solid #aaa; border-right-width: 0; display: none;">
  179. <a
  180. class="hide_rubric_link"
  181. style="float: right; margin-right:0 !important;"
  182. title="{{#t}}Hide Rubric{{/t}}"
  183. role="button"
  184. aria-label="{{#t}}Hide Rubric{{/t}}"
  185. tabindex='0'
  186. ><i class="icon-x standalone-icon"></i></a>
  187. <div id="rubric_assessments_list" style="text-align: right; margin-bottom: 5px; <%= hidden if @assessment_request || @visible_rubric_assessments.empty? %>">
  188. <%= before_label('show_assessment_by', 'Show Assessment By') %>
  189. <select id="rubric_assessments_select">
  190. <% @visible_rubric_assessments.each do |assessment| %>
  191. <option id="rubric_assessment_option_<%= assessment.id %>" value="<%= assessment.id %>">
  192. <% if can_do(assessment, @current_user, :read_assessor) %>
  193. <%= assessment.assessor_name %>
  194. <% else %>
  195. {{#t}}Anonymous User{{/t}}
  196. <% end %>
  197. </option>
  198. <% end %>
  199. <% if can_do(@context, @current_user, :manage_grades) && @submission.user != @current_user %>
  200. <% unless @visible_rubric_assessments.map{|a| a.assessor_id}.include?(@current_user.id) %>
  201. <option value="new" id="new_rubric_assessment_option">{{#t}}[New Assessment]{{/t}}</option>
  202. <% end %>
  203. <% end %>
  204. </select>
  205. </div>
  206. <% if @assignment.rubric.present? %>
  207. <%= render({
  208. partial: 'shared/rubric',
  209. object: @assignment.rubric,
  210. locals: {
  211. assessing: @submission.grants_right?(@current_user, :grade) || currently_peer_reviewing
  212. }}) %>
  213. <% end %>
  214. {{> views/shared/rubric_criterion_dialog}}
  215. <div class="button-container">
  216. <% if @assignment.rubric_association.user_can_assess_for?(assessor: @current_user, assessee: @submission.user) %>
  217. <button type="button" class="save_rubric_button btn btn-small">{{#t}}Save Comment{{/t}}</button>
  218. <% end %>
  219. </div>
  220. <a href="<%= context_url(@context, :context_rubric_association_rubric_assessments_url, @assignment.rubric_association) %>" class="update_rubric_assessment_url" style="display: none;">&nbsp;</a>
  221. </div>
  222. <% end %>
  223. <div style="display: none;">
  224. <% if !currently_peer_reviewing && can_do(@context, @current_user, :manage_grades) %>
  225. <a style="display: none;" title="POST" href="<%= context_url(@context, :update_submission_context_gradebook_url) %>" class="update_submission_url">&nbsp;</a>
  226. <% else %>
  227. <a style="display: none;" title="PUT" href="<%= context_url(@context, :context_assignment_submission_url, @submission.assignment_id, @submission.user_id) %>" class="update_submission_url">&nbsp;</a>
  228. <% end %>
  229. <a style="display: none;" href="<%= context_url(@context, :context_assignment_submission_url, @submission.assignment_id, @submission.user_id) %>" class="submission_data_url">&nbsp;</a>
  230. </div>
  231. <div class="submission-details-container">
  232. <div class="submission-details-frame">
  233. <iframe id="preview_frame" src="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @submission.user_id, :preview => 1, :rand => rand(999999)) %>" allowfullscreen="true" frameborder="0" style="border: 0; width: 100%; height: 300px; display: block;" title="{{#t}}Preview{{/t}}"></iframe>
  234. </div>
  235. <div class="submission-details-comments" style="word-wrap: break-word; min-width: 1%;">
  236. <div style="background-color: #fff;">
  237. <a href="#" class="comments_link" style="display: none; <%= 'font-weight: bold;' unless @submission.submission_comments.empty? %>">Comments <% unless @submission.submission_comments.empty? %>(<%= @submission.submission_comments.length %>)<% end %></a>
  238. <div class="comments">
  239. <button type="button" class="btn button-secondary cancel_comment_button" style="display: none; float: right; margin-right:0 !important;"><%= image_tag("delete_circle.png", :alt => t('Delete')) %></button>
  240. <div class="comment_list" aria-live="polite" style="padding: 10px; clear:right;">
  241. <% unless @submission.user_can_read_grade?(@current_user, session) %>
  242. <% if @assignment.muted? %>
  243. <i>{{#t}}You may not see all comments right now because the assignment is currently being graded{{/t}}</i>
  244. <% else %>
  245. <i>{{#t}}As a peer reviewing student, you will only see comments written by you.{{/t}}</i>
  246. <% end %>
  247. <br/><br/>
  248. <% end %>
  249. <% @submission.visible_submission_comments.each do |comment| %>
  250. <% if can_do(comment, @current_user, :read) %>
  251. <div class="comment <%= 'draft' if comment.draft? %>" id="submission_comment_<%= comment.id %>" style="margin-bottom: 10px;">
  252. <div class="comment" style="color: #444;">
  253. <% if comment.media_comment_id && comment.media_comment_type %>
  254. <div class="comment_media">
  255. {{#t}}media_comment_link', "This is a media comment, *click here to view*.", :wrapper => '<br/><a href="#" class="play_comment_link media-comment">\1</a>.{{/t}}
  256. <span class="media_comment_id" style="display: none;"><%= comment.media_comment_id %></span>
  257. <div class="media_comment_content">
  258. </div>
  259. </div>
  260. <% else %>
  261. <span style="white-space: pre-wrap;"><%= comment.comment %></span>
  262. <% end %>
  263. </div>
  264. <div class="comment_attachments" style="text-align: right; margin-right: 10px;">
  265. <% comment.attachments.each do |attachment| %>
  266. <div class="comment_attachment">
  267. <a href="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @submission.user_id, :comment_id => comment.id, :download => attachment.id) %>" class="comment_attachment_link <%= attachment.mime_class %>"><%= attachment.display_name %></a>
  268. </div>
  269. <% end %>
  270. </div>
  271. <div style="text-align: right; font-size: 0.8em; color: #888;">
  272. <span class="author_name">
  273. <%= comment_author_name_for(comment) %>
  274. </span>,
  275. <span class="posted_at"><%= datetime_string(comment.created_at) %></span>
  276. </div>
  277. </div>
  278. <% end %>
  279. <% end %>
  280. </div>
  281. <div class="comment_media" id="comment_media_blank" style="display: none; white-space: normal;">
  282. {{#t}}media_comment_link', "This is a media comment, *click here to view*.", :wrapper => '<br/><a href="#" class="play_comment_link media-comment">\1</a>.{{/t}}
  283. <span class="media_comment_id" style="display: none;">&nbsp;</span>
  284. <div class="media_comment_content">
  285. </div>
  286. </div>
  287. <div class="comment_attachment" id="comment_attachment_blank" style="display: none;">
  288. <a class="comment_attachment_link" href="<%= context_url(@context, :context_assignment_submission_url, @assignment.id, @submission.user_id, :comment_id => "{{ comment_id }}", :download => "{{ id }}") %>"><span class="display_name">&nbsp;</span></a>
  289. </div>
  290. <div class="comment" id="comment_blank" style="display: none; margin-bottom: 10px;">
  291. <span class="comment" style="color: #444; white-space: pre-wrap;"></span>
  292. <div class="comment_attachments" style="text-align: right; margin-right: 10px;"></div>
  293. <div style="text-align: right; font-size: 0.8em; color: #888;">
  294. <span class="author_name">&nbsp;</span>,
  295. <span class="posted_at">&nbsp;</span>
  296. </div>
  297. </div>
  298. <div class="comment_attachment_input nobr" id="comment_attachment_input_blank" style="display: none;">
  299. <input type="file" name="attachments[-1][uploaded_data]"/>
  300. <a href="#" class="delete_comment_attachment_link no-hover"><i class="icon-end" role="presentation"></i></a>
  301. </div>
  302. <div id="media_media_recording" style="display: none;">
  303. <div class="media_recording">
  304. </div>
  305. </div>
  306. <div style="padding: 10px; <%= hidden unless can_do(@submission, @current_user, :comment) %>" id="add_comment_form">
  307. <strong><%= before_label('add_a_comment', 'Add a Comment') %></strong>
  308. <span><br/>{{#t}}Teachers and submitter will be notified of all comments.{{/t}}</span>
  309. <textarea class="ic-Input grading_comment"></textarea>
  310. <div class="comment_attachments">
  311. </div>
  312. <div class="clearfix" style="text-align: right;">
  313. <% if feature_enabled?(:kaltura) %>
  314. <a href="#" style="float: left;" class="media_comment_link media-comment">{{#t}}Media Comment{{/t}}</a>
  315. <% end %>
  316. <a href="#" style="float: right;" class="attach_comment_file_link">{{#t}}Attach File{{/t}}</a>
  317. <div class="clear"></div>
  318. </div>
  319. <% if @assignment.has_group_category? && can_do(@submission, @current_user, :make_group_comment) %>
  320. <label class="checkbox" for="submission_group_comment">
  321. <input type="checkbox" name="group_comment" id="submission_group_comment"/>
  322. {{#t}}Send Comment to the Whole Group{{/t}}
  323. </label>
  324. <% end %>
  325. <div class="button-container">
  326. <button type="button" class="Button Button--primary save_comment_button">{{#t}}Save{{/t}}</button>
  327. </div>
  328. </div>
  329. </div>
  330. </div>
  331. </div>
  332. </div>
  333. <% js_env :rubricAssessments => @visible_rubric_assessments.as_json(:include => :assessor, :permissions => {:user => @current_user, :session => session}) %>