Skip to content

Commit

Permalink
Merge 6403d80 into e696088
Browse files Browse the repository at this point in the history
  • Loading branch information
samarth-p committed Dec 5, 2023
2 parents e696088 + 6403d80 commit 2b60657
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 123 deletions.
251 changes: 154 additions & 97 deletions app/controllers/teams_controller.rb
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,185 +1,242 @@
# frozen_string_literal: true

# TeamsController manages CRUD operations for teams, encompassing creation, updating, listing, and deletion.
class TeamsController < ApplicationController
include AuthorizationHelper
include TeamsControllerHelper

autocomplete :user, :name

# Check if the current user has TA privileges
# Checks if the current user has Teaching Assistant (TA) privileges
def action_allowed?
current_user_has_ta_privileges?
end

# attempt to initialize team type in session
# Attempts to initialize the team type in the session
def init_team_type(type)
return unless type && Team.allowed_types.include?(type)

session[:team_type] = type
end

# retrieve an object's parent by its ID
def parent_by_id(id)
# Retrieves an object's parent by its ID
def find_parent_by_id(id)
Object.const_get(session[:team_type]).find(id)
end

# retrieve an object's parent from the object's parent ID
def parent_from_child(child)
# Retrieves an object's parent from the object's parent ID
def find_parent_from_child(child)
Object.const_get(session[:team_type]).find(child.parent_id)
end

# This function is used to create teams with random names.
# Instructors can call by clicking "Create teams" icon and then click "Create teams" at the bottom.
# Creates teams with random names, enabling instructors to create teams through a dedicated interface
def create_teams
parent = parent_by_id(params[:id])
Team.randomize_all_by_parent(parent, session[:team_type], params[:team_size].to_i)
undo_link('Random teams have been successfully created.')
ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Random teams have been successfully created', request)
redirect_to action: 'list', id: parent.id
parent = find_parent_by_id(params[:id])
create_random_teams(parent)
log_team_creation
redirect_to_team_list(parent.id)
rescue TeamExistsError => e
handle_team_exists_error(parent.id, e.message)
end

# Displays list of teams for a parent object(either assignment/course)
# Displays a list of teams for a parent object (either an assignment or course)
def list
init_team_type(params[:type])
@assignment = Assignment.find_by(id: params[:id]) if session[:team_type] == Team.allowed_types[0]
@is_valid_assignment = session[:team_type] == Team.allowed_types[0] && @assignment.max_team_size > 1
@assignment = find_assignment(params[:id]) if assignment?
@is_valid_assignment = valid_assignment?
begin
@root_node = Object.const_get(session[:team_type] + 'Node').find_by(node_object_id: params[:id])
@child_nodes = @root_node.get_teams
rescue StandardError
flash[:error] = $ERROR_INFO
team_nodes(params[:id])
rescue StandardError => e
flash[:error] = "An error occurred: #{e.message}"
# Log the error for investigation if needed
Rails.logger.error("Error in TeamsController#list: #{e.message}")
end
end

# Create an empty team manually
# Determines if the session type represents an assignment
def assignment?
session[:team_type] == Team.allowed_types[0]
end

# Finds an assignment by its ID
def find_assignment(id)
Assignment.find_by(id: id)
end

# Checks if the assignment is valid based on predefined conditions
def valid_assignment?
assignment? && @assignment.max_team_size > 1
end

# Sets team nodes associated with an ID
def team_nodes(id)
@root_node = Object.const_get("#{session[:team_type]}Node").find_by(node_object_id: id)
@child_nodes = @root_node.get_teams
end

# Initializes creation of an empty team manually
def new
init_team_type(Team.allowed_types[0]) unless session[:team_type]
@parent = Object.const_get(session[:team_type]).find(params[:id])
end

# Called when a instructor tries to create an empty team manually
def create
parent = parent_by_id(params[:id])
# Handles creation of a team manually by an instructor
def create_team_manually
parent = find_parent_by_id(params[:id])
begin
Team.check_for_existing(parent, params[:team][:name], session[:team_type])
@team = Object.const_get(session[:team_type] + 'Team').create(name: params[:team][:name], parent_id: parent.id)
TeamNode.create(parent_id: parent.id, node_object_id: @team.id)
undo_link("The team \"#{@team.name}\" has been successfully created.")
redirect_to action: 'list', id: parent.id
create_team(parent)
create_team_node(parent)
set_undo_link_for_team_creation
redirect_to_team_list(parent.id)
rescue TeamExistsError
flash[:error] = $ERROR_INFO
redirect_to action: 'new', id: parent.id
handle_team_exists_error(parent.id)
end
end

# Update the team
# Updates team information
def update
@team = Team.find(params[:id])
parent = parent_from_child(@team)
@team = find_team(params[:id])
parent = find_parent_from_child(@team)

begin
Team.check_for_existing(parent, params[:team][:name], session[:team_type])
@team.name = params[:team][:name]
@team.save
flash[:success] = "The team \"#{@team.name}\" has been successfully updated."
undo_link('')
redirect_to action: 'list', id: parent.id
update_team_name(parent, params[:team][:name])
set_success_flash_for_update
undo_link_for_update
redirect_to_team_list(parent.id)
rescue TeamExistsError
flash[:error] = $ERROR_INFO
redirect_to action: 'edit', id: @team.id
handle_team_exists_error_for_update(@team.id)
end
end

# Edit the team
# Finds a team by its ID
def find_team(id)
Team.find(id)
end

# Edits team details
def edit
@team = Team.find(params[:id])
end

# Deleting all teams associated with a given parent object
# Deletes all teams associated with a given parent object
def delete_all
root_node = Object.const_get(session[:team_type] + 'Node').find_by(node_object_id: params[:id])
child_nodes = root_node.get_teams.map(&:node_object_id)
Team.destroy_all if child_nodes
redirect_to action: 'list', id: params[:id]
root_node = find_root_node(params[:id])
child_nodes = get_child_node_ids(root_node)

delete_teams(child_nodes) unless child_nodes.empty?
redirect_to_team_list(params[:id])
end

# Deleting a specific team associated with a given parent object
# Finds the root node by its ID
def find_root_node(id)
Object.const_get("#{session[:team_type]}Node").find_by(node_object_id: id)
end

# Gets child node IDs associated with a root node
def get_child_node_ids(root_node)
root_node.get_teams.map(&:node_object_id)
end

# Deletes a specific team associated with a given parent object
def delete
# delete records in team, teams_users, signed_up_teams table
@team = Team.find_by(id: params[:id])
unless @team.nil?
@signed_up_team = SignedUpTeam.where(team_id: @team.id)
@teams_users = TeamsUser.where(team_id: @team.id)

if @signed_up_team == 1 && !@signUps.first.is_waitlisted # if a topic is assigned to this team
# if there is another team in waitlist, assign this topic to the new team
topic_id = @signed_up_team.first.topic_id
next_wait_listed_team = SignedUpTeam.where(topic_id: topic_id, is_waitlisted: true).first
# Save the topic's new assigned team and delete all waitlists for this team
SignUpTopic.assign_to_first_waiting_team(next_wait_listed_team) if next_wait_listed_team
end

@sign_up_team.destroy_all if @sign_up_team
@teams_users.destroy_all if @teams_users
@team.destroy if @team
undo_link("The team \"#{@team.name}\" has been successfully deleted.")
end
redirect_back fallback_location: root_path
@team = find_team_for_deletion(params[:id])
return redirect_back(fallback_location: root_path) if @team.nil?

handle_team_sign_ups(@team)
delete_associated_records(@team)
undo_link_for_deletion(@team.name)
redirect_back(fallback_location: root_path)
end

# Finds a team for deletion by its ID
def find_team_for_deletion(id)
Team.find_by(id: id)
end

# Copies existing teams from a course down to an assignment
# The team and team members are all copied.
# Copies existing teams from a course down to an assignment, including team members
def inherit
copy_teams(Team.team_operation[:inherit])
end

# Handovers all teams to the course that contains the corresponding assignment
# The team and team members are all copied.
def bequeath_all
if session[:team_type] == Team.allowed_types[1]
flash[:error] = 'Invalid team type for bequeath all'
redirect_to controller: 'teams', action: 'list', id: params[:id]
else
copy_teams(Team.team_operation[:bequeath])
end
# Transfers all teams to the course corresponding to the assignment
def transfer_all
return redirect_with_error if invalid_team_type_for_transfer?

copy_teams(Team.team_operation[:bequeath])
rescue StandardError => e
flash[:error] = "An error occurred: #{e.message}"
# Log the error for investigation if needed
Rails.logger.error("Error in TeamsController#transfer_all: #{e.message}")
end

# Checks if the team type is invalid for transfer
def invalid_team_type_for_transfer?
session[:team_type] == Team.allowed_types[1]
end

def redirect_with_error
flash[:error] = 'Invalid team type for bequeath all'
redirect_to controller: 'teams', action: 'list', id: params[:id]
end

# Method to abstract the functionality to copy teams.
def copy_teams(operation)
assignment = Assignment.find(params[:id])
assignment = find_assignment_for_copy(params[:id])
if assignment.course_id
choose_copy_type(assignment, operation)
else
flash[:error] = 'No course was found for this assignment.'
flash_error_copy
end
redirect_to controller: 'teams', action: 'list', id: assignment.id
redirect_to_team_list(assignment.id)
end

def find_assignment_for_copy(id)
Assignment.find(id)
end

def flash_error_copy
flash[:error] = 'No course was found for this assignment.'
end

def redirect_to_team_list_to_copy(assignment_id)
redirect_to controller: 'teams', action: 'list', id: assignment_id
end

# Abstraction over different methods
def choose_copy_type(assignment, operation)
course = Course.find(assignment.course_id)
if operation == Team.team_operation[:bequeath]
bequeath_copy(assignment, course)
transfer_copy(assignment, course)
else
inherit_copy(assignment, course)
end
end

# Method to perform a copy of assignment teams to course
def bequeath_copy(assignment, course)
teams = assignment.teams
if course.course_teams.any?
flash[:error] = 'The course already has associated teams'
else
Team.copy_content(teams, course)
flash[:note] = teams.length.to_s + ' teams were successfully copied to "' + course.name + '"'
def transfer_copy(assignment, course)
if course_has_teams?(course)
flash_error('The course already has associated teams')
return
end

copy_teams_to_course(assignment.teams, course)
end

# Method to inherit teams from course by copying
def inherit_copy(assignment, course)
teams = course.course_teams
if teams.empty?
flash[:error] = 'No teams were found when trying to inherit.'
else
Team.copy_content(teams, assignment)
flash[:note] = teams.length.to_s + ' teams were successfully copied to "' + assignment.name + '"'
if course_teams_empty?(course)
flash_error('No teams were found when trying to inherit.')
return
end

copy_teams_to_assignment(course.course_teams, assignment)
end

def course_has_teams?(course)
course.course_teams.any?
end

def course_teams_empty?(course)
course.course_teams.empty?
end
end

0 comments on commit 2b60657

Please sign in to comment.