-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
324 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.