Skip to content

Commit

Permalink
Merge branch 'main' into grading_audit_trail
Browse files Browse the repository at this point in the history
  • Loading branch information
dinesh-pasupuleti committed Apr 28, 2024
2 parents 6826cb7 + af5f58e commit 13b9830
Show file tree
Hide file tree
Showing 87 changed files with 1,302 additions and 343 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Expand Up @@ -24,7 +24,7 @@ jobs:
run: |
codespell --ignore-words=.github/config/codespell.txt \
--exclude-file=.github/config/codespell.txt \
--skip="./db/migrate,./spec/fixtures,./spec/controllers/grades_controller_spec.rb"
--skip="./db/migrate,./spec/fixtures,./spec/controllers/grades_controller_spec.rb,./config/name.yml"
misspell:
name: Check spelling all files in commit with misspell
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Expand Up @@ -4,10 +4,10 @@ on:
workflow_dispatch:
pull_request:
branches: [main, development]
paths-ignore: ['**.md', '**.yml']
paths-ignore: ['**.md']
push:
branches: [main, development]
paths-ignore: ['**.md', '**.yml']
paths-ignore: ['**.md']

jobs:
test:
Expand Down
184 changes: 105 additions & 79 deletions app/assets/javascripts/grading.js
@@ -1,83 +1,109 @@
function toggleAll(numteams){
var maintag = document.getElementById('teamAll');
hidden = maintag.innerHTML == 'Show all teams';
if (hidden) {maintag.innerHTML = 'Hide all teams';}
else {maintag.innerHTML = 'Show all teams';}
toggleTeams(numteams,hidden);
function toggleAll(numteams) {
var maintag = document.getElementById('teamAll');
visible = maintag.innerHTML == 'Show all teams';
if (visible) {
maintag.innerHTML = 'Hide all teams';
} else {
maintag.innerHTML = 'Show all teams';
}
toggleTeams(numteams, visible);
}

function collapseObj(obj, atag){
obj.style.display = 'none';
atag.innerHTML = '<img src="/assets/expand.png">';

files = document.getElementById(obj.id+'_files');
if (files) {
files.style.display = 'none';
files_tag = document.getElementById(obj.id+'_filesLink');
if (files_tag){files_tag.innerHTML = 'show submission';}
}
reviews = document.getElementById(obj.id+'_reviews');
if (reviews) {
reviews.style.display = 'none';
reviews_tag = document.getElementById(obj.id+'_reviewsLink');
if (reviews_tag){reviews_tag.innerHTML = 'show reviews';}
}
mreviews = document.getElementById(obj.id+'_mreviews');
if (mreviews) {
mreviews.style.display = 'none';
mreviews_tag = document.getElementById(obj.id+'_mreviewsLink');
if(mreviews_tag){mreviews_tag.innerHTML = 'show metareviews';}
}
previews = document.getElementById(obj.id+'_previews');
if (previews) {
previews.style.display = 'none';
previews_tag = document.getElementById(obj.id+'_previewsLink');
if(previews_tag){previews_tag.innerHTML = 'show teammate reviews';}
}
}

function toggleTeams(numteams,hidden){
for (var i = 0; i < numteams; i++){
elementId = 'team'+i;
var atag = document.getElementById(elementId+'Link');
var sublistsize = 1;
while (document.getElementById(elementId+"_"+sublistsize) != null){
var obj = document.getElementById(elementId+"_"+sublistsize);
if (hidden) {
obj.style.display = '';
atag.innerHTML = '<img src="/assets/collapse.png">';}
else {
collapseObj(obj, atag);
}
sublistsize += 1;
}
}
}

function toggleTeam(elementId){
var sublistsize = 1;
var obj = document.getElementById(elementId+"_"+sublistsize);
var atag = document.getElementById(elementId+'Link');
var header = document.getElementById(elementId+'_header');

while (obj != null){

function collapseObj(obj, atag, header) {
obj.style.display = 'none';
atag.innerHTML = '<img src="/assets/expand.png">';
header.style.backgroundColor = 'white';
header.style.color = "#000000";
var bExpand = obj.style.display.length == 0;
if (bExpand) {
collapseObj(obj, atag);
}
else {
obj.style.display = '';
//E1877: changes made to adjust width of expandables
var offsets = obj.getBoundingClientRect();
obj.style.width="calc(100vw - 103px)";
atag.innerHTML = '<img src="/assets/collapse.png">';
header.style.backgroundColor = '#a90201';
header.style.color = "#ffffff";
}
sublistsize += 1;
var obj = document.getElementById(elementId+"_"+sublistsize);
}
}

files = document.getElementById(obj.id + '_files');
if (files) {
files.style.display = 'none';
files_tag = document.getElementById(obj.id + '_filesLink');
if (files_tag) {
files_tag.innerHTML = 'show submission';
}
}
reviews = document.getElementById(obj.id + '_reviews');
if (reviews) {
reviews.style.display = 'none';
reviews_tag = document.getElementById(obj.id + '_reviewsLink');
if (reviews_tag) {
reviews_tag.innerHTML = 'show reviews';
}
}
mreviews = document.getElementById(obj.id + '_mreviews');
if (mreviews) {
mreviews.style.display = 'none';
mreviews_tag = document.getElementById(obj.id + '_mreviewsLink');
if (mreviews_tag) {
mreviews_tag.innerHTML = 'show metareviews';
}
}
previews = document.getElementById(obj.id + '_previews');
if (previews) {
previews.style.display = 'none';
previews_tag = document.getElementById(obj.id + '_previewsLink');
if (previews_tag) {
previews_tag.innerHTML = 'show teammate reviews';
}
}
}

function toggleTeams(numteams, visible) {
for (var i = 0; i < numteams; i++) {
var sublistsize = 1;
var elementId = 'team' + i;
var obj = document.getElementById(elementId + '_' + sublistsize);
var atag = document.getElementById(elementId + 'Link');
var header = document.getElementById(elementId + '_header');
if (atag) {
while (obj != null) {
var bExpand = obj.style.display.length == 0;
if (bExpand) {
if (!visible)
collapseObj(obj, atag, header);
} else {
if (visible) {
obj.style.display = '';
//E1877: changes made to adjust width of expandables
var offsets = obj.getBoundingClientRect();
obj.style.width = 'calc(100vw - 103px)';
atag.innerHTML = '<img src="/assets/collapse.png">';
header.style.backgroundColor = '#a90201';
header.style.color = "#ffffff";
}
}
sublistsize += 1;
var obj = document.getElementById(elementId + "_" + sublistsize);
}
}
}
}

function toggleTeam(elementId) {
var sublistsize = 1;
var obj = document.getElementById(elementId + '_' + sublistsize);
var atag = document.getElementById(elementId + 'Link');
var header = document.getElementById(elementId + '_header');
if (atag) {
while (obj != null) {

header.style.backgroundColor = 'white';
header.style.color = "#000000";
var bExpand = obj.style.display.length == 0;
if (bExpand) {
collapseObj(obj, atag);
} else {
obj.style.display = '';
//E1877: changes made to adjust width of expandables
var offsets = obj.getBoundingClientRect();
obj.style.width = 'calc(100vw - 103px)';
atag.innerHTML = '<img src="/assets/collapse.png">';
header.style.backgroundColor = '#a90201';
header.style.color = "#ffffff";
}
sublistsize += 1;
var obj = document.getElementById(elementId + '_' + sublistsize);
}
}
}
2 changes: 2 additions & 0 deletions app/controllers/assessment360_controller.rb
Expand Up @@ -163,6 +163,8 @@ def calc_overall_review_info(assignment,
# assign it as 0 instead of leaving it blank. This helps in easier calculation of overall grade
overall_review_grade_hash[assignment.id] = 0 unless overall_review_grade_hash.key?(assignment.id)
overall_review_count_hash[assignment.id] = 0 unless overall_review_count_hash.key?(assignment.id)
# Do not consider reviews that have not been filled out by teammates when calculating averages.
reviews = reviews.reject { |review| review.average_score == 'N/A' }
grades = 0
# Check if they person has gotten any review for the assignment
if reviews.count > 0
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/grades_controller.rb
Expand Up @@ -47,6 +47,7 @@ def view
end
end
@scores = review_grades(@assignment, @questions)
@num_reviewers_assigned_scores = @scores[:teams].length # After rejecting nil scores need original length to iterate over hash
averages = vector(@scores)
@average_chart = bar_chart(averages, 300, 100, 5)
@avg_of_avg = mean(averages)
Expand Down Expand Up @@ -89,8 +90,19 @@ def view_team
@vmlist = []

counter_for_same_rubric = 0
if @assignment.vary_by_topic?
topic_id = SignedUpTeam.topic_id_by_team_id(@team_id)
topic_specific_questionnaire = AssignmentQuestionnaire.where(assignment_id: @assignment.id, topic_id: topic_id).first.questionnaire
@vmlist << populate_view_model(topic_specific_questionnaire)
end
questionnaires.each do |questionnaire|
@round = nil

# Guard clause to skip questionnaires that have already been populated for topic specific reviewing
if @assignment.vary_by_topic? && questionnaire.type == 'ReviewQuestionnaire'
next # Assignments with topic specific rubrics cannot have multiple rounds of review
end

if @assignment.varying_rubrics_by_round? && questionnaire.type == 'ReviewQuestionnaire'
questionnaires = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id)
if questionnaires.count > 1
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/import_file_controller.rb
Expand Up @@ -184,7 +184,7 @@ def import_from_hash(session, params)
def hash_rows_with_headers(header, body)
new_body = []
if (params[:model] == 'User') || (params[:model] == 'AssignmentParticipant') || (params[:model] == 'CourseParticipant') || (params[:model] == 'SignUpTopic')
header.map!(&:to_sym)
header.map! { |str| str.strip.downcase.gsub(/\s+/, "").to_sym }
body.each do |row|
new_body << header.zip(row).to_h
end
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/lottery_controller.rb
Expand Up @@ -84,7 +84,11 @@ def construct_teams_bidding_info(unassigned_teams, sign_up_topics)
# teams
def create_new_teams_for_bidding_response(teams, assignment, users_bidding_info)
teams.each do |user_ids|
new_team = AssignmentTeam.create_team_with_users(assignment.id, user_ids)
if assignment.auto_assign_mentor
new_team = MentoredTeam.create_team_with_users(assignment.id, user_ids)
else
new_team = AssignmentTeam.create_team_with_users(assignment.id, user_ids)
end
# Select data from `users_bidding_info` variable that only related to team members in current team
current_team_members_info = users_bidding_info.select { |info| user_ids.include? info[:pid] }.map { |info| info[:ranks] }
Bid.merge_bids_from_different_users(new_team.id, assignment.sign_up_topics, current_team_members_info)
Expand Down
11 changes: 8 additions & 3 deletions app/controllers/participants_controller.rb
Expand Up @@ -36,12 +36,15 @@ def add
can_submit = permissions[:can_submit]
can_review = permissions[:can_review]
can_take_quiz = permissions[:can_take_quiz]
#E2351 - add corresponding duty fill from permissions
can_mentor = permissions[:can_mentor]
if curr_object.is_a?(Assignment)
curr_object.add_participant(params[:user][:name], can_submit, can_review, can_take_quiz)
curr_object.add_participant(params[:user][:name], can_submit, can_review, can_take_quiz, can_mentor)
elsif curr_object.is_a?(Course)
curr_object.add_participant(params[:user][:name])
end
user = User.find_by(name: params[:user][:name])
@model = params[:model]
@participant = curr_object.participants.find_by(user_id: user.id)
flash.now[:note] = "The user <b>#{params[:user][:name]}</b> has successfully been added."
rescue StandardError
Expand All @@ -58,11 +61,12 @@ def update_authorizations
can_submit = permissions[:can_submit]
can_review = permissions[:can_review]
can_take_quiz = permissions[:can_take_quiz]
can_mentor = permissions[:can_mentor]
parent_id = participant.parent_id
# Upon successfully updating the attributes based on user role, a flash message is displayed to the user after the
# change in the database. This also gives the user the error message if the update fails.
begin
participant.update_attributes(can_submit: can_submit, can_review: can_review, can_take_quiz: can_take_quiz)
participant.update_attributes(can_submit: can_submit, can_review: can_review, can_take_quiz: can_take_quiz, can_mentor: can_mentor)
flash[:success] = 'The role of the selected participants has been successfully updated.'
rescue StandardError
flash[:error] = 'The update action failed.'
Expand Down Expand Up @@ -194,7 +198,7 @@ def view_copyright_grants
def participant_params
params.require(:participant).permit(:can_submit, :can_review, :user_id, :parent_id, :submitted_at,
:permission_granted, :penalty_accumulated, :grade, :type, :handle,
:time_stamp, :digital_signature, :duty, :can_take_quiz)
:time_stamp, :digital_signature, :can_mentor, :can_take_quiz)
end

# Get the user info from the team user
Expand Down Expand Up @@ -230,3 +234,4 @@ def get_signup_topics_for_assignment(assignment_id, team_info, team_id)
has_topics
end
end

3 changes: 0 additions & 3 deletions app/controllers/popup_controller.rb
Expand Up @@ -87,9 +87,6 @@ def view_review_scores_popup
@assignment_id = params[:assignment_id]
@review_final_versions = ReviewResponseMap.final_versions_from_reviewer(@assignment_id, @reviewer_id)
@reviews = []

assignment = Assignment.find(@assignment_id)
flash.now[:error] = 'This report is not implemented for assignments where the rubric varies by topic.' if assignment.vary_by_topic?
end

# this can be called from "response_report" by clicking reviewer names from instructor end.
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/questionnaires_controller.rb
Expand Up @@ -19,7 +19,8 @@ def action_allowed?
@questionnaire = Questionnaire.find(params[:id])
current_user_has_admin_privileges? ||
(current_user_is_a?('Teaching Assistant') && Ta.find(session[:user].id).is_instructor_or_co_ta?(@questionnaire)) ||
(current_user_is_a?('Instructor') && current_user_id?(@questionnaire.try(:instructor_id)))
(current_user_is_a?('Instructor') && current_user_id?(@questionnaire.try(:instructor_id))) ||
(current_user_is_a?('Instructor') && Ta.get_my_instructors(@questionnaire.try(:instructor_id)).include?(session[:user].id))
else
current_user_has_student_privileges?
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/response_controller.rb
Expand Up @@ -157,7 +157,7 @@ def new
# So do the answers, otherwise the response object can't find the questionnaire when the user hasn't saved his new review and closed the window.
# A new response has to be created when there hasn't been any reviews done for the current round,
# or when there has been a submission after the most recent review in this round.
@response = @response.create_or_get_response(@map, @current_round)
@response = @response.create_or_get_response(@map, @current_round.to_i)
questions = sort_questions(@questionnaire.questions)
store_total_cake_score
init_answers(questions)
Expand Down

0 comments on commit 13b9830

Please sign in to comment.