forked from expertiza/expertiza
-
Notifications
You must be signed in to change notification settings - Fork 1
/
_review_report.html.erb
315 lines (280 loc) · 13.5 KB
/
_review_report.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<!-- the table creation is changed top accommodate functionality of tablesorter, which requires thead and tbody seperately. Previously, headers were in tbody only -->
<div class='reviewreport'>
<!-- Added headers for tablesorter -->
<script type='text/javascript'>
$(window).load(function () {
$("#myTable tbody");
//to add drag and drop, uncomment this, and comment the above line
//$("#myTable tbody").sortable();
$("#dialog").dialog({
autoOpen: false,
modal: true,
show: "blind",
hide: "blind",
buttons: {
Ok: function() {
$(this).dialog("close");
}
}
});
});
</script>
<div id="dialog" title="Success">Grade and comment for reviewer successfully saved.</div>
<!-- Sets the styling configuration for the review display based on the status of the review -->
<p> **In "Team reviewed" column text in:</p>
<ul style="list-style-type:square">
<li><i style="color:red">red</i> indicates that the review is not completed in any rounds;</li>
<li><i style="color:blue">blue</i> indicates that a review is completed in every round and the review grade is not assigned;</li>
<li><i style="color:green">green</i> indicates that there is no submitted work to review within the round;</li>
<li><i style="color:purple">purple</i> indicates that there is no review for a submitted work within the round;</li>
<li><i style="color: #986633">brown</i> indicates that the review grade has been assigned</li>
<li>✔ Check mark indicates that the student has given consent to make the reviews public</li>
</ul>
<p> </p>
<button onclick="exportTableToCSV('review_scores.csv')">Export Review Scores To CSV File</button>
<br />
<br />
<input type='button' onClick='javascript:showHideColumn(this);' value='Show'> AVG Feedback Scores Column
<br /><br>
<table id="myTable" class="table table-striped" width="100%" cellspacing='0' cellpadding='2' border='0'>
<thead>
<tr bgcolor='#CCCCCC'>
<!-- class value decides whether the column should be sortable or not -->
<th rowspan ="2" width="8%" class="sorter-true">Reviewer <span></span></th>
<th rowspan ="2" width="8%" class="sorter-true">Reviews done<span></span></th>
<th rowspan ="2" width="20%" class="sorter-true">Team reviewed <span></span></th>
<th width="5%" colspan= "2" class="sorter-false">Scores<span></span></th>
<th rowspan ="2" width="8%" class="sorter-false" >AVG Feedback Score<span></span></th>
<th rowspan ="2" width="14%" class="sorter-true">Metrics <span></span></th>
<th rowspan ="2" class="sorter-false">Assign grade and write comments <span></span></th>
</tr>
<tr bgcolor='#CCCCCC'>
<th width="4%" class="sorter-true" style="white-space:nowrap;"> Score awarded <span></span></th>
<th width="6%" class="sorter-true"> AVG Score <span></span></th>
</tr>
</thead>
<tbody>
<!-- Set the review data and row span for each reviewer -->
<% sort_reviewer_by_review_volume_desc.each_with_index do |reviewer, index| %>
<% @response_maps, @rspan = get_data_for_review_report(@id, reviewer.id, @type) %>
<tr>
<% unless reviewer.id == 1 %>
<% user = Participant.find(reviewer.id).user %>
<!--reviewer-->
<!-- added class attribute and span tag to extract full name and unityID of the user for scraping (Used in export to CSV functionality) -->
<td style="white-space:nowrap;">
<%= index + 1 %>.
<%= link_to user.name(session[:ip]), impersonate_impersonate_path(:user => {:name => user.name(session[:ip])}), :method => :post, :class => "user_unityID" %>
<br/>
(<span class="user_name"><%= user.fullname(session[:ip]) %></span>)
</td>
<!--# reviews done-->
<td align = 'left' style="white-space:nowrap;">
<% (1..@assignment.num_review_rounds).each do |round| %>
<%= instance_variable_get("@review_in_round_" + round.to_s) %>/<%= @rspan %>
<%= ', ' unless round == @assignment.num_review_rounds %>
<% end %>
<%= link_to "summary", {:controller => 'popup', :action => 'view_review_scores_popup', :reviewer_id => reviewer.id, :assignment_id=>@id}, target: :_blank %>
<br/>
<%= link_to "authors summary", {:controller => 'popup', :action => 'view_feedback_scores_popup', :reviewer_id => reviewer.id, :assignment_id => @id}, target: :_blank %>
</td>
<!--Team reviewed / Author feedback-->
<td align = 'left' style="white-space:nowrap;">
<% @response_maps.each_with_index do |reviewer_map, index| %>
<!--For assignments with team member 1, team reviewed column should show username instead of team name, which is randomly generated.-->
<% team_name_color = get_team_color(reviewer_map) %>
<% team_reviewed_link_name = get_team_reviewed_link_name(@assignment.max_team_size, reviewer_map.response, reviewer_map.reviewee_id, session[:ip]) %>
<% if Team.where(id: reviewer_map.reviewee_id).length > 0 %>
<!--Team reviewed-->
<% if index == 0 %>
<% if Response.exists?(map_id: reviewer_map.id) %>
<div id = <%= team_name_color %>>✔
<% else %>
<div id= <%= team_name_color %>>
<% end %>
<% else %>
<% if Response.exists?(map_id: reviewer_map.id) %>
<div id = <%= team_name_color %> style='border-top: solid; border-width: 1px;'>✔
<% else %>
<div id = <%= team_name_color %> style='border-top: solid; border-width: 1px;'>
<% end %>
<% end %>
<%= link_to team_reviewed_link_name, :controller => 'popup', :action => 'team_users_popup', :id => reviewer_map.reviewee_id, :id2 => reviewer_map.id, :assignment_id=>@id %>
<%= list_review_submissions(reviewer.id, reviewer_map.reviewee_id, reviewer_map.id) %>
<!--Hard-coded Dr.Kidd's question in order to display link.-->
<!--later we can create a hyperlink question type to deal with this situation.-->
<%= list_hyperlink_submission(reviewer_map.id, 5386) if Assignment.find_by(id: @id.to_i).try(:course).try(:instructor).try(:name) == 'Jkidd' %>
</div>
</div>
<% end %>
<% end %>
</td>
<!--Render partial view corresponding to the overall score awarded to a team-->
<td align='left' style="white-space:nowrap;">
<% @response_maps.each_with_index do |reviewer_map, index| %>
<% if Team.where(id: reviewer_map.reviewee_id).length > 0 %>
<% @team = Team.find(reviewer_map.reviewee_id) %>
<%= render partial: 'team_score_score_awarded', locals: {bgcolor: @bgcolor, team_id: @team.id, reviewer_id: reviewer.id} %>
<% end %>
<% end %>
</td>
<!--Render partial view corresponding to the average score awarded to a team-->
<td align='left' style="white-space:nowrap;">
<% @response_maps.each_with_index do |reviewer_map, index| %>
<% if Team.where(id: reviewer_map.reviewee_id).length > 0 %>
<% @team = Team.find(reviewer_map.reviewee_id) %>
<%= render partial: 'team_score', locals: {bgcolor: @bgcolor, team_id: @team.id, reviewer_id: reviewer.id} %>
<% end %>
<% end %>
</td>
<!--Render partial view corresponding to each author avg score in each round-->
<td align='left' style="white-space:nowrap;">
<% @response_maps.each_with_index do |reviewer_map, index| %>
<% if Team.where(id: reviewer_map.reviewee_id).length > 0 %>
<% @team = Team.find(reviewer_map.reviewee_id) %>
<%= render partial: 'author_scores_avg', locals: {bgcolor: @bgcolor, team_id: @team.id, reviewer_id: reviewer.id} %>
<% end %>
<% end %>
</td>
<!--Metrics-->
<td align='left' style="white-space:nowrap;">
<%= display_volume_metric_chart(reviewer) %>
</td>
<!--Assign grade and write comments-->
<td align='left' style="white-space:nowrap;">
<%= form_tag save_grade_and_comment_for_reviewer_review_mapping_index_path, remote: true do %>
<%= hidden_field_tag :participant_id, reviewer.id %>
<%= hidden_field_tag :assignment_id, @id %>
<%= number_field_tag 'grade_for_reviewer', reviewer.review_grade.try(:grade_for_reviewer), min: 0, max: 100, maxlength: 3, size: 3, placeholder: 'Grade' %>
<br/>
<%= text_area_tag 'comment_for_reviewer', reviewer.review_grade.try(:comment_for_reviewer), placeholder: 'Comment', class: "awesome_input", 'data-multiple' => '', 'data-minchars' => "1" %>
<table class="inline-transparent">
<tr>
<td>
<%= image_tag 'text_macro.png', :border => 2, :title => 'Text Macro/Pastebin', :style => 'width: 24px; height:30px', :onclick => 'show_text_macros()' %>
</td>
</tr>
<tr>
<td>
<%= submit_tag 'Save' %>
</td>
</tr>
</table>
<% end %>
</td>
<% end %>
</tr>
<% end %>
</table>
</div>
<!--Partial for text macro form-->
<%= render :partial => '/user_pastebins/save_text_macros' %>
<script>
$(function () {
/*Function for sorting the table */
$("#myTable").tablesorter({
sortList: [[0, 0]], //sort First Column by default when page loads
widgets: ['zebra'], // Make sure to update the css when column is sorted
headers: {
4: {
sorter: 'customParser' //custom Parser to parse Metrics data for the custom parser
}
}
});
});
$.tablesorter.addParser({
id: "customParser", //customParser for sorting by volume
is: function (stringValue) {
return false;
},
format: function (stringValue) {
var stringNumericPart = stringValue.split(" "); //split the data by spaces
var numericValue = parseInt(stringNumericPart[2], 10); //extract the numeric data
return numericValue;
},
type: 'numeric'
});
</script>
<script>
function downloadCSV(csv, filename) {
var csvFile;
var downloadLink;
// CSV file
csvFile = new Blob([csv], {type: "text/csv"});
// Download link
downloadLink = document.createElement("a");
// File name
downloadLink.download = filename;
// Create a link to the file
downloadLink.href = window.URL.createObjectURL(csvFile);
// Hide download link
downloadLink.style.display = "none";
// Add the link to DOM
document.body.appendChild(downloadLink);
// Click download link
downloadLink.click();
}
// Method to extract review report fields data from HTML Table and convert the data into CSV format.
// Currently, it will extract and store data for 'Full Name, Unity ID, Email ID, Grade and Comment' fields into CSV file
function exportTableToCSV(filename) {
var csv = [];
var rows = document.querySelector("table#myTable").rows;
var row = [];
row = setHeaderForCSV();
csv.push(row.join(","));
// for each row of information, pull the review report fields and save them to the corresponding variables
for (var i = 1; i < rows.length; i++) {
var row = [];
reviewer_name = "\"" + rows[i].querySelector("td span.user_name").innerHTML + "\"";
reviewer_unityid = rows[i].querySelector("td a.user_unityID").innerHTML;
reviewer_emailid = reviewer_unityid + "@ncsu.edu";
reviewer_grade = rows[i].querySelector("input#grade_for_reviewer").value;
reviewer_comment = "\"" + rows[i].querySelector("textarea#comment_for_reviewer").innerHTML.replace(/"/g,"\'") + "\"";
// push the information to set the information.
row.push(reviewer_name);
row.push(reviewer_unityid);
row.push(reviewer_emailid);
row.push(reviewer_grade);
row.push(reviewer_comment);
csv.push(row.join(","));
}
downloadCSV(csv.join("\n"), filename);
}
// Method to set names of header columns in Exported CSV file
function setHeaderForCSV() {
var row = [];
row.push("Name");
row.push("UnityID");
row.push("EmailID");
row.push("Grade");
row.push("Comment");
return row;
}
var row0_col=4;
var colNo1=5;
showHideColumn(null);
var doShow;
function showHideColumn(e) {
if (e != null) {
if (doShow) {
doShow = false;
e.value = 'Show';
} else {
e.value = 'Hide';
doShow = true;
}
}
var rows = document.getElementById('myTable').rows;
for (var row = 0; row < rows.length; row++) {
var cols = rows[row].cells;
if (row==0){
cols[row0_col].style.display = doShow ? '' : 'none';
}
else{
if (colNo1 >= 1 && colNo1 < cols.length) {
cols[colNo1].style.display = doShow ? '' : 'none';
}
}
}
}
</script>