CSC/ECE 517 Fall 2019 - Project E1965. Review report should link to the usual view for reviews: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(46 intermediate revisions by 2 users not shown)
Line 2: Line 2:


Expertiza<ref>https://expertiza.ncsu.edu/</ref> is an open-source web application to create re-usable learning objects through peer-reviews to facilitate incremental learning. Students can submit learning objects such as articles, wiki pages, repository links and with the help of peer reviews, improve them. The project has been developed using the Ruby on Rails<ref>https://en.wikipedia.org/wiki/Ruby_on_Rails</ref> framework and is supported by the [http://www.nsf.gov National Science Foundation].
Expertiza<ref>https://expertiza.ncsu.edu/</ref> is an open-source web application to create re-usable learning objects through peer-reviews to facilitate incremental learning. Students can submit learning objects such as articles, wiki pages, repository links and with the help of peer reviews, improve them. The project has been developed using the Ruby on Rails<ref>https://en.wikipedia.org/wiki/Ruby_on_Rails</ref> framework and is supported by the [http://www.nsf.gov National Science Foundation].
== Team members ==
# Jing Cai (jcai3@ncsu.edu)
# Hua Cao (hcao5@ncsu.edu)
# Sichao Yu (syu25@ncsu.edu)
# Mentor: Harsh Agrawal (hagrawa2@ncsu.edu)


== Project Description ==
== Project Description ==
Line 7: Line 13:
=== Purpose and Scope ===
=== Purpose and Scope ===


Expertiza assignments are based on a peer review system where the instructor creates rubrics for an assignment through questionnaires which students use to review other students' submissions. The author of the submission is given an opportunity to provide feedback about these reviews. Expertiza displays reviews (i) to the team who was reviewed, and (ii) to the reviewer.  A student user can see all the reviews of his/her team’s project.  The instructor can see all the reviews of everyone’s project.  The instructor also has access to a Review report, which shows, for each reviewer, all the reviews that (s)he wrote. Both score report and review report use different code so UI is non-orthogonal, it would be great if we can follow same UI structure for both score and review report which also reduce the DRY problems. There is no functionality for user to search between reviews of particular project, such a functionality will help user to search through all reviews for specific problem they are trying to focus on.
Expertiza assignments are based on a peer review system where the instructor creates rubrics for an assignment through questionnaires which students use to review other students' submissions. The author of the submission is given an opportunity to provide feedback about these reviews. Expertiza displays reviews (i) to the team who was reviewed, and (ii) to the reviewer.  A student user can see all the reviews of his/her team’s project.  The instructor can see all the reviews of everyone’s project.  The instructor also has access to a Review report, which shows, for each reviewer, all the reviews that (s)he wrote. The score report and review report use different code so UI is non-orthogonal, it would be great if we can follow same UI structure for score and review report which also reduce the DRY problems.


=== Task Description ===
=== Task Description ===
Line 16: Line 22:
==== Task ====
==== Task ====
Currently, if you pull up a review report, and then click on one of the teams reviewed, e.g., the first one, you get a report that looks like this:
Currently, if you pull up a review report, and then click on one of the teams reviewed, e.g., the first one, you get a report that looks like this:
[[File:Current_review.png]]
[[File:Team user popup before.png]]  


We need to change the views to existing templates in view_my_scores pages.
We need to change the views to existing templates in view_my_scores pages.
Line 23: Line 29:
For student view the UI is consistent in displaying reviews they have done and reviews they have received but for instructor's view the review report follows different UI and have different code. To make the UI consistent we have decided to choose the UI design of student view as the base and modify the UI design for review report in instructor's view. This will allow us to use the same code in both views, thereby following DRY principle.
For student view the UI is consistent in displaying reviews they have done and reviews they have received but for instructor's view the review report follows different UI and have different code. To make the UI consistent we have decided to choose the UI design of student view as the base and modify the UI design for review report in instructor's view. This will allow us to use the same code in both views, thereby following DRY principle.


Previous View:


[[File:review_report.png]]
Updated View:


Updated View:
[[File:Team user popup after.png]]


[[File:review-report-changed.png]]
Our changes can shown more apparently in the following video.<ref>https://youtu.be/Kd6iaHIT3Y8</ref>


== Implementation ==
== Implementation ==
Line 35: Line 40:


=== Files modified in this project ===
=== Files modified in this project ===
*team_users_popup.html.erb
*app/view/pop_up/team_users_popup.html.haml
*app/view/pop_up/team_users_popup.html.erb
*app/assets/stylesheets/grades.scss


=== Solution ===
=== Solution ===
The specific changes can be seemed in the comments of code.


Review report view is rendered in app/views/popup/team_users_popup.html.haml. In this view, we populate table by iterating over each question under each round. While same approach was used previously but here we replace each row by a predefined format used for rendering question similar to student view.
Review report view is rendered in app/views/popup/team_users_popup.html.haml. First, we changed it to regular erb file. And fix some bugs between auto-change.


<pre>
<pre>
Line 70: Line 78:
</pre>
</pre>


We replace the above code by code below, here in each row we invoke view_completed_question method defined in Criterion.rb for scored questions which insert the html code to render question,score,comments.
We replace the above code by code below. Just simply convert haml to erb.
<pre>
      <table border="1px solid #ccc" class="general">
        <tr>
          <th align="left" width="50%">Question</th>
          <th width="5%">Score</th>
          <th width="45%">Comments</th>
        </tr>
        <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
          <tr>
            <td align="left">
              <%= answer.question.txt %>
            </td>
            <% if answer.question.is_a?(ScoredQuestion) %>
              <td align="center">
                <%= answer.answer %>
                \/#{instance_variable_get('@max_score_round_' + round.to_s)}
              </td>
            <% elsif answer.question.is_a?(Checkbox) %>
              <td align="center">
                <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
              </td>
            <% else %>
              <td align="center">
                <%= answer.answer %>
              </td>
            <% end %>
            <td align="left">
              <%= answer.comments %>
            </td>
          </tr>
        <% end %>
        <tr>
          <th>Reviewer Score (Σ weighted score/Σ weighted available score)</th>
          <td align="center">
            <%= instance_variable_get('@sum_round_' + round.to_s) %>
            \/#{instance_variable_get('@total_possible_round_' + round.to_s)}
          </td>
          <td align="left">
            \= #{instance_variable_get('@total_percentage_round_' + round.to_s)}
          </td>
        </tr>
      </table>
</pre>
 
Then we change the row and col layout and css style of this view.
The previous tables can be listed as below.
<pre>
<table border="1px solid #ccc" class="general">
        <tr>
          <th align="left" width="50%">Question</th>
          <th width="5%">Score</th>
          <th width="45%">Comments</th>
        </tr>
        <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
          <tr>
            <td align="left">
              <%= answer.question.txt %>
            </td>
            <% if answer.question.is_a?(ScoredQuestion) %>
              <td align="center">
                <%= answer.answer %>
                /<%= instance_variable_get('@max_score_round_' + round.to_s) %>
              </td>
            <% elsif answer.question.is_a?(Checkbox) %>
              <td align="center">
                <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
              </td>
            <% else %>
              <td align="center">
                <%= answer.answer %>
              </td>
            <% end %>
            <td align="left">
              <%= answer.comments %>
            </td>
          </tr>
</pre>
After we change the lay out, it can be listed as below.
<pre>
      <table class="table table-striped grades">
      <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
      <tr>
        <th colspan="2">
          <%= answer.question.seq.to_i %>
          <%= '. ' %>
          <%= answer.question.txt %>
          <%= '[Max points: '%>
          <%= instance_variable_get('@max_score_round_' + round.to_s) %>
          <%= ']'%>
        </th>
      </tr>
 
      <tr>
        <% if answer.question.is_a?(ScoredQuestion) %>
          <td align="left" width="5%">
            <%= answer.answer %>
          </td>
        <% elsif answer.question.is_a?(Checkbox) %>
          <td align="left" width="5%>
            <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
          </td>
        <% end %>
          <td align="left" width="95%">
            <%= answer.comments %>
          </td>
      </tr>
    <% end %>
</pre>
 
We also fixed some small bug about the checkbox questions and index of the questions.
We fixed the if-else logic question, in order that checkbox  questions can be showed properly.
<pre>
        <% if answer.question.is_a?(ScoredQuestion) %>
            <%= answer.question.seq.to_i %>
            <%= '. ' %>
            <%= answer.question.txt %>
            <%= '[Max points: '%>
            <%= instance_variable_get('@max_score_round_' + round.to_s) %>
            <%= ']'%>
          <% elsif answer.question.is_a?(Checkbox) %>
            <%= answer.question.seq.to_i %>
            <%= '.' %>&nbsp;
            <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
            <%= answer.question.txt %>
          <% end %>
</pre>
We also changed the outlook of score and make it to be a circle.
<pre>
          <td align="left" width="5%">
            <div class="c<%= answer.answer %> grade-circle"><%= answer.answer %></div>
        </td>
</pre>
And the css is in grades.scss
<pre>
/* This is a grade circle for different grades. */
.grade-circle {
  width:30px;
  height:30px;
  border-radius:50%;
  font-size:15px;
  color:black;
  line-height:30px;
  text-align:center;
}
</pre>
 
We added the "index" in this view, in order to show the proper sequence of review's question.
<pre>
      <% index = 1 %>
      <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
      <tr class="warning">
        <th colspan="2">
          <%= index%>
          <% if answer.question.is_a?(ScoredQuestion) %>
            <%= '. ' %>
            <%= '.  ' %>
            <%= answer.question.txt %>
            <%= '[Max points: '%>
            <%= instance_variable_get('@max_score_round_' + round.to_s) %>
            <%= ']'%>
            <% index = index +1 %>
          <% elsif answer.question.is_a?(Checkbox) %>
            <%= '.' %>&nbsp;
            <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
            <%= answer.question.txt %>
            <% index = index + 1 %>
          <% end %>
</pre>


At last, we add the css style "warning" and "info" for the table and review score. So that it looks more beautiful.
<pre>
<pre>
      %table{:border => "1px solid #ccc" ,:class => "table table-bordered"}
<tr class="warning">
         - counter = 0
         <th colspan="2">
        - instance_variable_get('@scores_round_' + round.to_s).each do |s|
          <% if answer.question.is_a?(ScoredQuestion) %>
          - counter += 1
            <%= answer.question.seq.to_i %>
          - row_class = counter.even? ? "info" : "warning"
        </th>
          - question = Question.find(s.question_id)
      </tr>
           %tr{:class => row_class}
 
             %td
<tr class="info">
              = question.becomes(Criterion).view_completed_question(counter,s,instance_variable_get('@max_score_round_' + round.to_s))
      <% if answer.question.is_a?(ScoredQuestion) %>
        %tr
           <td align="left" width="5%">
          %td{:style => "font-weight:bold"}
             <div class="c<%= answer.answer %>" style="width:30px; height:30px; border-radius:50%; font-size:15px; color:black; line-height:30px; text-align:center;"><%= answer.answer %></div>
            = 'Reviewer Score (Σ weighted score/Σ weighted available score) = '+ instance_variable_get('@sum_round_' + round.to_s).to_s |
 
            \/ #{instance_variable_get('@total_possible_round_' + round.to_s)} (#{instance_variable_get('@total_percentage_round_' + round.to_s)}%)
      %table
</pre>
</pre>


==UI Testing==
==Test Plan==
Our test plan are mostly manual. There are two reasons why we choose UI testing:
# As we only change the layout of several views. We can only test them from UI testing.
# The existing templates view_my_score are also tested with UI, without any Rspec testing.
 
There are two test cases for UI testing.
* To Test UI for student View
* To Test UI for student View
** Log-in as Student.
** Log-in as Student.
Line 100: Line 280:
** Go to Manage Assignments
** Go to Manage Assignments
** Click on review report of a particular assignment
** Click on review report of a particular assignment
** Click on any item in team reviewed tab, to see reviews.


== Future Improvements ==
'''Expected result:'''
 
[[File:Team user popup after.png]]


== References ==
== References ==
<references/>
<references/>
== Other Links ==
#[https://github.com/ljxxcaijing/expertiza/tree/beta  GitHub Repository]
#[https://github.com/expertiza/expertiza/pull/1532  GitHub Pull Request]
#[https://youtu.be/Kd6iaHIT3Y8  Youtube Video Demo]

Latest revision as of 18:56, 6 November 2019

Introduction

Expertiza<ref>https://expertiza.ncsu.edu/</ref> is an open-source web application to create re-usable learning objects through peer-reviews to facilitate incremental learning. Students can submit learning objects such as articles, wiki pages, repository links and with the help of peer reviews, improve them. The project has been developed using the Ruby on Rails<ref>https://en.wikipedia.org/wiki/Ruby_on_Rails</ref> framework and is supported by the National Science Foundation.

Team members

  1. Jing Cai (jcai3@ncsu.edu)
  2. Hua Cao (hcao5@ncsu.edu)
  3. Sichao Yu (syu25@ncsu.edu)
  4. Mentor: Harsh Agrawal (hagrawa2@ncsu.edu)

Project Description

Purpose and Scope

Expertiza assignments are based on a peer review system where the instructor creates rubrics for an assignment through questionnaires which students use to review other students' submissions. The author of the submission is given an opportunity to provide feedback about these reviews. Expertiza displays reviews (i) to the team who was reviewed, and (ii) to the reviewer. A student user can see all the reviews of his/her team’s project. The instructor can see all the reviews of everyone’s project. The instructor also has access to a Review report, which shows, for each reviewer, all the reviews that (s)he wrote. The score report and review report use different code so UI is non-orthogonal, it would be great if we can follow same UI structure for score and review report which also reduce the DRY problems.

Task Description

Background

  • Currently Review report uses its own code to display reviews. This a pretty basic view, and it does not interpret HTML codes. It should be changed so that it calls the usual code that is used for displaying reviews, that gives the circle with the score inside.

Task

Currently, if you pull up a review report, and then click on one of the teams reviewed, e.g., the first one, you get a report that looks like this:

We need to change the views to existing templates in view_my_scores pages.


For student view the UI is consistent in displaying reviews they have done and reviews they have received but for instructor's view the review report follows different UI and have different code. To make the UI consistent we have decided to choose the UI design of student view as the base and modify the UI design for review report in instructor's view. This will allow us to use the same code in both views, thereby following DRY principle.


Updated View:

Our changes can shown more apparently in the following video.<ref>https://youtu.be/Kd6iaHIT3Y8</ref>

Implementation

Files modified in this project

  • app/view/pop_up/team_users_popup.html.haml
  • app/view/pop_up/team_users_popup.html.erb
  • app/assets/stylesheets/grades.scss

Solution

The specific changes can be seemed in the comments of code.

Review report view is rendered in app/views/popup/team_users_popup.html.haml. First, we changed it to regular erb file. And fix some bugs between auto-change.

 %table{:border => "1px solid #ccc"}
        %tr
          %th{:align => "left", :width => "50%"} Question
          %th{:width => "5%"} Score
          %th{:width => "45%"} Comments
        - instance_variable_get('@scores_round_' + round.to_s).each do |s|
          %tr
            %td{:align => "left"}
              = Question.find(s.question_id).txt
            - if Question.find(s.question_id).is_a?(ScoredQuestion)
              %td{:align => "center"}
                = s.answer
                \/#{instance_variable_get('@max_score_round_' + round.to_s)}
            - else
              %td{:align => "center"}
                = s.answer
            %td{:align => "left"}
              = s.comments
        %tr
          %th Reviewer Score (Σ weighted score/Σ weighted available score)
          %td{:align => "center"}
            = instance_variable_get('@sum_round_' + round.to_s)
            \/#{instance_variable_get('@total_possible_round_' + round.to_s)}
          %td{:align => "left"}
            \= #{instance_variable_get('@total_percentage_round_' + round.to_s)}
      %table

We replace the above code by code below. Just simply convert haml to erb.

      <table border="1px solid #ccc" class="general">
        <tr>
          <th align="left" width="50%">Question</th>
          <th width="5%">Score</th>
          <th width="45%">Comments</th>
        </tr>
        <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
          <tr>
            <td align="left">
              <%= answer.question.txt %>
            </td>
            <% if answer.question.is_a?(ScoredQuestion) %>
              <td align="center">
                <%= answer.answer %>
                \/#{instance_variable_get('@max_score_round_' + round.to_s)}
              </td>
            <% elsif answer.question.is_a?(Checkbox) %>
              <td align="center">
                <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
              </td>
            <% else %>
              <td align="center">
                <%= answer.answer %>
              </td>
            <% end %>
            <td align="left">
              <%= answer.comments %>
            </td>
          </tr>
        <% end %>
        <tr>
          <th>Reviewer Score (Σ weighted score/Σ weighted available score)</th>
          <td align="center">
            <%= instance_variable_get('@sum_round_' + round.to_s) %>
            \/#{instance_variable_get('@total_possible_round_' + round.to_s)}
          </td>
          <td align="left">
            \= #{instance_variable_get('@total_percentage_round_' + round.to_s)}
          </td>
        </tr>
      </table>

Then we change the row and col layout and css style of this view. The previous tables can be listed as below.

<table border="1px solid #ccc" class="general">
        <tr>
          <th align="left" width="50%">Question</th>
          <th width="5%">Score</th>
          <th width="45%">Comments</th>
        </tr>
        <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
          <tr>
            <td align="left">
              <%= answer.question.txt %>
            </td>
            <% if answer.question.is_a?(ScoredQuestion) %>
              <td align="center">
                <%= answer.answer %>
                /<%= instance_variable_get('@max_score_round_' + round.to_s) %>
              </td>
            <% elsif answer.question.is_a?(Checkbox) %>
              <td align="center">
                <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
              </td>
            <% else %>
              <td align="center">
                <%= answer.answer %>
              </td>
            <% end %>
            <td align="left">
              <%= answer.comments %>
            </td>
          </tr>

After we change the lay out, it can be listed as below.

      <table class="table table-striped grades">
      <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
      <tr>
        <th colspan="2">
          <%= answer.question.seq.to_i %>
          <%= '. ' %>
          <%= answer.question.txt %>
          <%= '[Max points: '%>
          <%= instance_variable_get('@max_score_round_' + round.to_s) %>
          <%= ']'%>
        </th>
      </tr>

      <tr>
        <% if answer.question.is_a?(ScoredQuestion) %>
          <td align="left" width="5%">
            <%= answer.answer %>
          </td>
        <% elsif answer.question.is_a?(Checkbox) %>
          <td align="left" width="5%>
            <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
          </td>
        <% end %>
          <td align="left" width="95%">
            <%= answer.comments %>
          </td>
      </tr>
    <% end %>

We also fixed some small bug about the checkbox questions and index of the questions. We fixed the if-else logic question, in order that checkbox questions can be showed properly.

        <% if answer.question.is_a?(ScoredQuestion) %>
            <%= answer.question.seq.to_i %>
            <%= '. ' %>
            <%= answer.question.txt %>
            <%= '[Max points: '%>
            <%= instance_variable_get('@max_score_round_' + round.to_s) %>
            <%= ']'%>
          <% elsif answer.question.is_a?(Checkbox) %>
            <%= answer.question.seq.to_i %>
            <%= '.' %> 
            <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
            <%= answer.question.txt %>
          <% end %>

We also changed the outlook of score and make it to be a circle.

          <td align="left" width="5%">
            <div class="c<%= answer.answer %> grade-circle"><%= answer.answer %></div>
         </td>

And the css is in grades.scss

/* This is a grade circle for different grades. */
.grade-circle {
  width:30px; 
  height:30px; 
  border-radius:50%; 
  font-size:15px; 
  color:black; 
  line-height:30px; 
  text-align:center;
}

We added the "index" in this view, in order to show the proper sequence of review's question.

      <% index = 1 %>
      <% instance_variable_get('@scores_round_' + round.to_s).each do |answer| %>
      <tr class="warning">
        <th colspan="2">
          <%= index%>
          <% if answer.question.is_a?(ScoredQuestion) %>
            <%= '. ' %>
            <%= '.  ' %>
            <%= answer.question.txt %>
            <%= '[Max points: '%>
            <%= instance_variable_get('@max_score_round_' + round.to_s) %>
            <%= ']'%>
            <% index = index +1 %>
          <% elsif answer.question.is_a?(Checkbox) %>
            <%= '.' %> 
            <%= answer.answer==0 ? image_tag("delete_icon.png"): image_tag("Check-icon.png") %>
            <%= answer.question.txt %>
            <% index = index + 1 %>
          <% end %>

At last, we add the css style "warning" and "info" for the table and review score. So that it looks more beautiful.

<tr class="warning">
        <th colspan="2">
          <% if answer.question.is_a?(ScoredQuestion) %>
            <%= answer.question.seq.to_i %>
        </th>
      </tr>

<tr class="info">
      <% if answer.question.is_a?(ScoredQuestion) %>
          <td align="left" width="5%">
            <div class="c<%= answer.answer %>" style="width:30px; height:30px; border-radius:50%; font-size:15px; color:black; line-height:30px; text-align:center;"><%= answer.answer %></div>

Test Plan

Our test plan are mostly manual. There are two reasons why we choose UI testing:

  1. As we only change the layout of several views. We can only test them from UI testing.
  2. The existing templates view_my_score are also tested with UI, without any Rspec testing.

There are two test cases for UI testing.

  • To Test UI for student View
    • Log-in as Student.
    • Go to Assignment
    • Click Your scores
    • Click show reviews
  • To Test UI for instructor View
    • Log-in as Instructor.
    • Go to Manage Assignments
    • Click on review report of a particular assignment

Expected result:

References

<references/>

Other Links

  1. GitHub Repository
  2. GitHub Pull Request
  3. Youtube Video Demo