CSC/ECE 517 Fall 2019 - E1966. Tabbed reviews partial file refactor for displaying the alternate view of reviews: Difference between revisions
No edit summary |
|||
Line 7: | Line 7: | ||
1) On student | 1) On student end, Expertiza uses grades/_reviews.html.erb partial file to display reviewers, scores and review details; on instructor end, it uses Response model methods to construct html file for review pages. We need to use the same kinds of partials in instructor-end and student-end. | ||
How to get the view of reviewers, scores and review details on student end? Click "Alternate View" button, and click "show reviews" link. The reviewers and scores pop up on the top and review details are below them. | |||
How to get the view of reviewers, scores and review details on instructor end? Click "Scores" for a certain assignment and choose a team. Click "Statistics" tab and then reviewers and scores table show up. Click "Reviews" tab and then click one of students' name link in the table head. And a new page pops up with review details. | |||
2) Give Feedback link at view_my_score at student-end should not appear at folded view. | 2) Give Feedback link at view_my_score at student-end should not appear at folded view. | ||
Where to find Give Feedback link? On student end, click "Alternate View" button and click "show reviews" link. At the bottom of a certain review, a give feedback link shows up. | |||
===What to do=== | ===What to do=== |
Revision as of 00:03, 29 October 2019
About Expertiza
Expertiza is a open source project currently for CSC517 instructor and students forming groups, submit work, review, and view grades. The project is based on Ruby on Rails framework and the code is on Github: https://github.com/expertiza/expertiza. Expertiza serves wiki page, collecting information of all internal information and updates of all versions.
Problem Statement
Issue details
1) On student end, Expertiza uses grades/_reviews.html.erb partial file to display reviewers, scores and review details; on instructor end, it uses Response model methods to construct html file for review pages. We need to use the same kinds of partials in instructor-end and student-end.
How to get the view of reviewers, scores and review details on student end? Click "Alternate View" button, and click "show reviews" link. The reviewers and scores pop up on the top and review details are below them. How to get the view of reviewers, scores and review details on instructor end? Click "Scores" for a certain assignment and choose a team. Click "Statistics" tab and then reviewers and scores table show up. Click "Reviews" tab and then click one of students' name link in the table head. And a new page pops up with review details.
2) Give Feedback link at view_my_score at student-end should not appear at folded view. Where to find Give Feedback link? On student end, click "Alternate View" button and click "show reviews" link. At the bottom of a certain review, a give feedback link shows up.
What to do
1) We need to use the same kinds of partials in instructor-end and student-end. So we decide to use grades/_team_statistics.html.erb to display reviewers and scores and to use grades/_tabbed_reviews.html.erb to display review details for both student-end and instructor-end.
2) Give Feedback link at view_my_score should appear at the bottom of expanded view.
Solution
For student end, split reviews.html.erb into two partial files. One is grades/team_review_statistics.html.erb for reviewers and scores. The other one is grades/tabbed_reviews.html.erb for review details. For instructor end, it used to use response model methods to construct html files for review details, now we use grades/tabbed_reviews.html.erb to display review details. So student end and instructor end both use grades/team_review_statistics and grades/tabbed_reviews to display reviewers, scores and review details.
Deploy Link
Our project is deployed at VCL
Student End
- In student end, render grades/team_review_statistics and grades/tabbed_reviews two partial files instead of grades/reviews partial file.
app/views/grades/_participant.html.erb
<TR id="<%= prefix %>_reviews" style="display:none; background-color: white;"> <TD COLSPAN="10"> <%= render :partial=>'grades/team_review_statistics', :locals => {:prefix => 'user', :participant => participant, :pscore => pscore} %> <%= render :partial=>'grades/tabbed_reviews', :locals => {:prefix => 'user', :participant => participant, :rscore => pscore[:review]} %> </TD> </TR>
- Add feed back link in student end view.
app/views/grades/_tabbed_reviews.html.erb
<% if controller.action_name == "view_my_scores"%> <!-- Generate the feedback html --> <% map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: participant.id).first review_feedbacks = map.try :response %> <% if review_feedbacks && !review_feedbacks.empty? %> <%= link_to "View", :controller => 'response', :action => 'view', :id => review_feedbacks.first.id %> or <%= link_to "Edit", :controller => 'response', :action => 'edit', :id => review_feedbacks.first.id, :return => "feedback" %> feedback for Review <%= count %> <% else %> <%= link_to "Give feedback", :controller => 'response', :action => 'new_feedback', :id => review.id %> for Review <%= count %> <% end %> </td></tr> <% end %>
- Add javascript to tabbed review so it can be hidden or shown by clicking the show/hide reviews.
app/views/grades/_tabbed_reviews.html.erb
<script type="text/javascript"> toggle_tag_prompt = function() { $('.tag_prompt_container').toggle(); }; $( document ).ready(function() { $('#tag_prompt_toggler').click(function () { if ($('#tag_prompt_toggler').text() == "hide tags") $('#tag_prompt_toggler').text("show tags") else $('#tag_prompt_toggler').text("hide tags") }); }); </script>
- Add statistics view to student end by using the team_review_statistics.html.erb file.
app/views/grades/_participant.html.erb
<TR id="<%= prefix %>_reviews" style="display:none; background-color: white;"> <TD COLSPAN="10"> <%= render :partial=>'grades/team_review_statistics', :locals => {:prefix => 'user', :participant => participant, :pscore => pscore} %> <%= render :partial=>'grades/tabbed_reviews', :locals => {:prefix => 'user', :participant => participant, :rscore => pscore[:review]} %> </TD> </TR>
app/views/grades/_team_review_statistics.html.erb
<% if controller.action_name != "view_my_scores"%> <tr> <td colspan="10"> <% end %> <% if controller.action_name != "view_my_scores"%> </td> </tr> <% end %>
Instructor End
- Create new method view2 for response_controller
app/controllers/response_controller.rb
def view2 @response = Response.find(params[:id]) @map = @response.map set_content2 render "response/view" end ...... ...... @participant = @map.reviewer ...... def set_content2(new_response = false) @contributor = @map.contributor members = TeamsUser.where(team_id: params[:team]) @user = members.first @participant = AssignmentParticipant.where(user_id: @user.user_id, parent_id: params[:assignment]).first @@ -264,7 +273,9 @@ def set_content(new_response = false) @questions = retrieve_questions questionnaires, @assignment.id # @pscore has the newest versions of response for each response map, and only one for each response map (unless it is vary rubric by round) @pscore = @participant.scores(@questions) @reviewer = @map.reviewer @round = params[:round] end
app/views/grades/_tabbed_reviews.html.erb
<% prefix = nil %> ...... <% if controller.action_name == "view_my_scores"%> <!-- Generate the feedback html --> <% map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: participant.id).first review_feedbacks = map.try :response %> <% if review_feedbacks && !review_feedbacks.empty? %> <%= link_to "View", :controller => 'response', :action => 'view', :id => review_feedbacks.first.id %> or <%= link_to "Edit", :controller => 'response', :action => 'edit', :id => review_feedbacks.first.id, :return => "feedback" %> feedback for Review <%= count %> <% else %> <%= link_to "Give feedback", :controller => 'response', :action => 'new_feedback', :id => review.id %> for Review <%= count %> <% end %> </td></tr> <% end %> <% end %> </table><hr> <% end %>
app/views/grades/_view_heatgrid.html.erb
<th class="sorter-false"> <a target="_blank" href="../response/view2?id=<%= review.id.to_s %>&&team=<%= @team.id %>&&round=<%= vm.round.to_s %>&&assignment=<%= @assignment.id %>" data-toggle="tooltip" data-placement="right" title="Click to see details"><%= user_name.to_s %></a> </th>
app/views/response/view.html.erb
<% if controller.action_name != "view2" %> <% file_url = nil %> <%= @response.display_as_html(nil, nil, file_url) %> <br/> <% else %> <TR style="display:none; background-color: white;"> <TD COLSPAN="10"> <%= render :partial=>'grades/tabbed_reviews', :locals => {:prefix => 'user', :participant => @participant, :rscore => @pscore[:review], :reviewer => @reviewer, :round => @round} %> </TD> </TR> <% end %>
- show right round for instructor-end
app/views/grades/_tabbed_reviews.html.erb
<% next if round.to_s != @round.to_s %>
- Create construct_instructor2_html in order to not show review number
app/models/response.rb
if prefix == "instructor" self_id = self.id.to_s code = construct_instructor2_html identifier, self_id, count elsif prefix # has prefix means view_score page in instructor end self_id = prefix + '_' + self.id.to_s code = construct_instructor_html identifier, self_id, count ...... def construct_instructor2_html identifier, self_id, count identifier += '<table width="100%">'\ '<tr>'\ '<td align="left" width="70%"><b>Review ' + '</b> '\ '<a href="#" name= "review_' + self_id + 'Link" onClick="toggleElement(' + "'review_" + self_id + "','review'" + ');return false;">hide review</a>'\ '</td>'\ '<td align="left"><b>Last Reviewed:</b>'\ "<span>#{(self.updated_at.nil? ? 'Not available' : self.updated_at.strftime('%A %B %d %Y, %I:%M%p'))}</span></td>"\ '</tr></table>' end
app/views/grades/_tabbed_reviews.html.erb
<% if controller.action_name != "view2"%> <h3>Round <%= round %></h3> <% if controller.action_name != "view_my_scores" %> <a href="#" name= <%= participant.id.to_s + '_' + round.to_s + "Link" %> onClick="toggleElement('<%= participant.id.to_s + '_' + round.to_s %>','round <%= round.to_s%> reviews');return false;">show round <%= round.to_s%> reviews</a> <% end %> <% end %> <% if @assignment.is_answer_tagging_allowed %> <span class="spn_qsttog" id="tag_prompt_toggler" title="Click to display/hide tags" onclick="toggle_tag_prompt()">hide tags</span> @@ -37,6 +39,7 @@ <% review_feedback = nil %> <% count = count + 1 %> <% prefix = nil %> <% prefix = "instructor" if controller.action_name == "view2" %>
- Show just one review in instructor-end
app/views/grades/_tabbed_reviews.html.erb
<% rounds.each do |round| %> <% if controller.action_name == "view2"%> <% next if round.to_s != @round.to_s %> <% end %> <% if controller.action_name != "view2"%> <h3>Round <%= round %></h3> <% if controller.action_name != "view_my_scores" %> @@ -33,8 +35,13 @@ <% if @assignment.is_answer_tagging_allowed %> <span class="spn_qsttog" id="tag_prompt_toggler" title="Click to display/hide tags" onclick="toggle_tag_prompt()">hide tags</span> <% end %> <% if controller.action_name != "view2"%> <table class="table table-striped" id=<%= participant.id.to_s + '_' + round.to_s %> <%= style="display: none;" if controller.action_name != "view_my_scores"%>> <% end %> <% rscore[:assessments].select{|response| response.round == round}.reverse.uniq{|response| response.map_id}.sort_by{|response| response.map_id}.each_with_index do |review, index| %> <% if controller.action_name == "view2"%> <% next if review.reviewer != @reviewer || count > 0 %> <% end %> <tr><td> <% review_feedback = nil %> <% count = count + 1 %> @@ -72,7 +79,9 @@ </td></tr> <% end %> <% end %> <% if controller.action_name != "view2"%> </table><hr> <% end %> <% end %> <% else %>
Test files
- tabbed_review_spec.rb created and added 3 test cases for alternate view of reviews
spec/features/tabbed_review_spec.rb
require "spec_helper" require 'rspec' describe "alternate view of reviews" do before(:each) do assignment1 = create(:assignment, name: "111", directory_path: 'test_assignment') create_list(:participant, 3) create(:assignment_node) create(:deadline_type, name: "submission") create(:deadline_type, name: "review") create(:deadline_type, name: "metareview") create(:deadline_type, name: "drop_topic") create(:deadline_type, name: "signup") create(:deadline_type, name: "team_formation") create(:deadline_right) create(:deadline_right, name: 'Late') create(:deadline_right, name: 'OK') create(:assignment_due_date, deadline_type: DeadlineType.where(name: 'review').first, due_at: Time.now.in_time_zone + 1.day) create(:topic) create(:topic, topic_name: "TestReview") create(:team_user, user: User.where(role_id: 2).first) create(:team_user, user: User.where(role_id: 2).second) create(:assignment_team) create(:team_user, user: User.where(role_id: 2).third, team: AssignmentTeam.second) create(:signed_up_team) create(:signed_up_team, team_id: 2, topic: SignUpTopic.second) create(:assignment_questionnaire) create(:question) # create(:review_response_map, reviewer_id: User.where(role_id: 2).third.id) # create(:review_response_map, reviewer_id: User.where(role_id: 2).second.id, reviewee: AssignmentTeam.second) # sleep(10000) end def load_alternate login_as('student2064') expect(page).to have_content "User: student2064" expect(page).to have_content "111" click_link "111" expect(page).to have_content "Submit or Review work for 111" expect(page).to have_content "Alternate View" click_link "Alternate View" expect(page).to have_content "Contributor" end it "shows the correct alternate view" do # Load questionnaire with generic setup load_alternate expect(page).to have_content "Contributor" expect(page).to have_content "Stats" expect(page).to have_content "Submitted work" expect(page).to have_content "Author Feedback" expect(page).to have_content "Teammate Review" expect(page).to have_content "Final Score" expect(page).to have_content "Range" expect(page).to have_content "Average" expect(page).to have_content "student2064" expect(page).to have_css "a[href='#']", text: 'hide stats' expect(page).to have_css "a[href='#']", text: 'show submission' #expect(page).to have_css "a[href='#']", text: 'show reviews' #page.should have_selector('table tr', text: 'show reviews') #find(:xpath, "//tr[contains(.,'show reviews')]/td/a", :text => 'show reviews').click #expect(page).to have_content "Writeup" end #describe "grades/participant", :type => :view do #it 'exists' do #find(:xpath, "//tr[contains(.,'show reviews')]/td/a", :text => 'show reviews').click #end #end end describe "test for instructor" do before(:each) do # assignment and topic create(:assignment, name: "Test Assignment", directory_path: "Test Assignment", rounds_of_reviews: 2, staggered_deadline: true, max_team_size: 1, allow_selecting_additional_reviews_after_1st_round: true) create_list(:participant, 3) create(:topic, topic_name: "Topic_1") create(:topic, topic_name: "Topic_2") create(:topic, topic_name: "Topic_3") assignment_id = Assignment.where(name: 'Test Assignment')[0].id #visit "/response/view2?id=#{review_id}&&team=#{team_id}&&round=1&&assignment=#{assignment_id}" # rubric create(:questionnaire, name: "TestQuestionnaire1") create(:questionnaire, name: "TestQuestionnaire2") create(:question, txt: "Question1", questionnaire: ReviewQuestionnaire.where(name: 'TestQuestionnaire1').first, type: "Criterion") create(:question, txt: "Question2", questionnaire: ReviewQuestionnaire.where(name: 'TestQuestionnaire2').first, type: "Criterion") create(:assignment_questionnaire, questionnaire: ReviewQuestionnaire.where(name: 'TestQuestionnaire1').first, used_in_round: 1) create(:assignment_questionnaire, questionnaire: ReviewQuestionnaire.where(name: 'TestQuestionnaire2').first, used_in_round: 2) questionnaire_id = ReviewQuestionnaire.first.id.to_s # deadline type create(:deadline_type, name: "submission") create(:deadline_type, name: "review") create(:deadline_type, name: "metareview") create(:deadline_type, name: "drop_topic") create(:deadline_type, name: "signup") create(:deadline_type, name: "team_formation") create(:deadline_right) create(:deadline_right, name: 'Late') create(:deadline_right, name: 'OK') create(:team_user, user: User.where(role_id: 2).first) create(:team_user, user: User.where(role_id: 2).second) create(:assignment_team) create(:team_user, user: User.where(role_id: 2).third, team: AssignmentTeam.second) create(:signed_up_team) create(:signed_up_team, team_id: 2, topic: SignUpTopic.second) visit "response/view2?id=#{questionnaire_id}&&team=1&&round=1&&assignment=#{assignment_id}" end it "can go to review details" do expect(page).to have_content "Toggle navigation" expect(page).to have_content "Papers on Expertiza" expect(page).to have_content "response" end end
Team Information
- Forked Issue on Github
- Weiran Fu (@ncsu.edu)
- Qingyan Wang (qwang20@ncsu.edu)
- Hongli Wang (hwang85@ncsu.edu)
- Mentor: Mohit Jain (mjain6@ncsu.edu)