Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions app/controllers/admin/graduationManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from app.controllers.admin import admin_bp

from app.logic.bonner import getBonnerCohorts
from app.logic.graduationManagement import setGraduatedStatus, getGraduationManagementUsers
from app.logic.graduationManagement import setGraduatedStatus, getGraduationManagementUsers, updateHideGraduatedStudents


@admin_bp.route('/admin/graduationManagement', methods=['GET'])
Expand All @@ -19,14 +19,20 @@ def graduationManagement():

@admin_bp.route('/<username>/setGraduationStatus/', methods=['POST'])
def setGraduationStatus(username):
"""
This function
username: unique value of a user to correctly identify them
"""
if not g.current_user.isAdmin:
abort(403)

status = request.form["status"]
setGraduatedStatus(username, status)

return ""

@admin_bp.route("/admin/hideGraduatedStudents/<username>", methods=["POST"])
def hideGraduatedStudents(username):
if g.current_user.isStudent:
abort(403)

checked = request.form["checked"]
updateHideGraduatedStudents(username, checked)

return ""
10 changes: 8 additions & 2 deletions app/controllers/admin/userManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,14 @@ def userManagement():

currentPrograms = currentPrograms.group_by(Program.id)

currentAdmins = list(User.select().where(User.isCeltsAdmin))
currentStudentStaff = list(User.select().where(User.isCeltsStudentStaff))
# hide graduated students if the user has indicated it
hideGraduatedStudents = User.get(username=g.current_user).hideGraduatedStudents
hideGraduatedStudentsWhere = True
if hideGraduatedStudents:
hideGraduatedStudentsWhere = (User.hasGraduated == False)

currentAdmins = list(User.select().where(User.isCeltsAdmin, hideGraduatedStudentsWhere))
currentStudentStaff = list(User.select().where(User.isCeltsStudentStaff, hideGraduatedStudentsWhere))
if g.current_user.isCeltsAdmin or g.current_user.isProgramManager:
return render_template('admin/userManagement.html',
terms = terms,
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/main/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,14 +581,15 @@ def updateTranscript(username, program_id):
@main_bp.route('/searchUser/<query>', methods = ['GET'])
def searchUser(query):

category= request.args.get("category")
category = request.args.get("category")
alwaysShowGraduatedStudents = int(request.args.get("alwaysShowGraduatedStudents", 0))

'''Accepts user input and queries the database returning results that matches user search'''
try:
query = query.strip()
search = query.upper()
splitSearch = search.split()
searchResults = searchUsers(query,category)
searchResults = searchUsers(query, category, alwaysShowGraduatedStudents)
return searchResults
except Exception as e:
print(e)
Expand Down
15 changes: 12 additions & 3 deletions app/logic/graduationManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from app.models.bonnerCohort import BonnerCohort
from app.logic.minor import getMinorProgress

def getGraduationManagementUsers():
def getGraduationManagementUsers(alwaysShowGraduatedStudents=False):
"""
Function to fetch all senior students along with their CCE Minor Progress and Bonner Status
"""
Expand All @@ -15,7 +15,7 @@ def getGraduationManagementUsers():
.join(BonnerCohort, JOIN.LEFT_OUTER, on=(BonnerCohort.user == User.username))
.where((User.rawClassLevel == 'Senior') | (User.rawClassLevel == "Graduating") | (User.hasGraduated == True)))

cceStudents = set([user["username"] for user in getMinorProgress()])
cceStudents = set([user["username"] for user in getMinorProgress(alwaysShowGraduatedStudents)])

graduationManagementUsers = []
for user in eligibleUsers:
Expand All @@ -39,4 +39,13 @@ def setGraduatedStatus(username, status):
gradStudent.hasGraduated = int(status)

gradStudent.save()


def updateHideGraduatedStudents(username, checked):
user = User.get(User.username == username)

# it is necessary we cast this to an int instead of a bool because the
# status is passed as a string and if we cast it to a bool it will always be True
user.hideGraduatedStudents = int(checked)

user.save()

17 changes: 11 additions & 6 deletions app/logic/minor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
from app.models.individualRequirement import IndividualRequirement
from app.models.certificationRequirement import CertificationRequirement
from app.models.cceMinorProposal import CCEMinorProposal
from app.models.attachmentUpload import AttachmentUpload
from app.logic.createLogs import createActivityLog
from app.logic.fileHandler import FileHandler
from app.logic.serviceLearningCourses import deleteCourseObject
from app.models.attachmentUpload import AttachmentUpload

from app.logic.utils import getHideGraduatedStudentsWhereClause

def createSummerExperience(username, formData):
"""
Expand Down Expand Up @@ -74,20 +74,24 @@ def getMinorInterest() -> List[Dict]:
"""
Get all students that have indicated interest in the CCE minor and return a list of dicts of all interested students
"""
hideGraduatedStudentsWhere = getHideGraduatedStudentsWhereClause(g.current_user)

interestedStudents = (User.select(User)
.join(IndividualRequirement, JOIN.LEFT_OUTER, on=(User.username == IndividualRequirement.username))
.where(User.isStudent & User.minorInterest & ~User.declaredMinor & IndividualRequirement.username.is_null(True)))
.where(User.isStudent & User.minorInterest & ~User.declaredMinor & IndividualRequirement.username.is_null(True), hideGraduatedStudentsWhere))

interestedStudentList = [model_to_dict(student) for student in interestedStudents]

return interestedStudentList

def getMinorProgress():
def getMinorProgress(alwaysShowGraduatedStudents=True):
"""
Get all the users who have an IndividualRequirement record under the CCE certification which
and returns a list of dicts containing the student, how many engagements they have completed,
and if they have completed the summer experience.
"""
hideGraduatedStudentsWhere = getHideGraduatedStudentsWhereClause(g.current_user) if not alwaysShowGraduatedStudents else (True)

summerCase = Case(None, [(CCEMinorProposal.proposalType == "Summer Experience", 1)], 0)

engagedStudentsWithCount = (
Expand All @@ -97,7 +101,7 @@ def getMinorProgress():
.join(IndividualRequirement, on=(User.username == IndividualRequirement.username))
.join(CertificationRequirement, on=(IndividualRequirement.requirement_id == CertificationRequirement.id))
.switch(User).join(CCEMinorProposal, JOIN.LEFT_OUTER, on= (User.username == CCEMinorProposal.student))
.where(CertificationRequirement.certification_id == Certification.CCE)
.where(CertificationRequirement.certification_id == Certification.CCE, hideGraduatedStudentsWhere)
.group_by(User.firstName, User.lastName, User.username)
.order_by(SQL("engagementCount").desc())
)
Expand Down Expand Up @@ -186,7 +190,8 @@ def getDeclaredMinorStudents():
"""
Get a list of the students who have declared minor
"""
declaredStudents = User.select().where(User.isStudent & User.declaredMinor)
hideGraduatedStudentsWhere = getHideGraduatedStudentsWhereClause(g.current_user)
declaredStudents = User.select().where(User.isStudent & User.declaredMinor, hideGraduatedStudentsWhere)

interestedStudentList = [model_to_dict(student) for student in declaredStudents]

Expand Down
11 changes: 9 additions & 2 deletions app/logic/searchUsers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from playhouse.shortcuts import model_to_dict
from flask import g
from app.models.user import User
def searchUsers(query, category=None):
def searchUsers(query, category=None, alwaysShowGraduatedStudents=False):
'''
Search the User table based on the search query and category

Expand All @@ -11,6 +12,12 @@ def searchUsers(query, category=None):
firstName = splitSearch[0] + "%"
lastName = " ".join(splitSearch[1:]) +"%"

excludeGraduatedStudentsWhere = True
# this is necessary if they just recently changed this and it hasn't updated yet, maybe?
currentUser = User.get(username=g.current_user)
if (currentUser.hideGraduatedStudents) and (not alwaysShowGraduatedStudents):
excludeGraduatedStudentsWhere = (User.hasGraduated == False)

if len(splitSearch) == 1: # search for query in first OR last name
searchWhere = (User.firstName ** firstName | User.lastName ** firstName | User.username ** splitSearch)
else: # search for first AND last name
Expand All @@ -30,6 +37,6 @@ def searchUsers(query, category=None):
userWhere = (User.isStudent)

# Combine into query
searchResults = User.select().where(searchWhere, userWhere)
searchResults = User.select().where(searchWhere, userWhere, excludeGraduatedStudentsWhere)

return { user.username : model_to_dict(user) for user in searchResults }
10 changes: 10 additions & 0 deletions app/logic/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from peewee import DoesNotExist

from app.models.term import Term
from app.models.user import User

def selectSurroundingTerms(currentTerm, prevTerms=2, summerOnly=False):
"""
Expand Down Expand Up @@ -98,3 +99,12 @@ def setRedirectTarget(target):
"""
session["redirectTarget"] = target

def getHideGraduatedStudentsWhereClause(username):

# hide graduated students if the user has indicated it
hideGraduatedStudents = User.get(username=username).hideGraduatedStudents
hideGraduatedStudentsWhere = True
if hideGraduatedStudents:
hideGraduatedStudentsWhere = (User.hasGraduated == False)

return hideGraduatedStudentsWhere
1 change: 1 addition & 0 deletions app/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class User(baseModel):
minorInterest = BooleanField(null=True)
hasGraduated = BooleanField(default=False)
declaredMinor = BooleanField(default=False)
hideGraduatedStudents = BooleanField(default=False)

# override BaseModel's __init__ so that we can set up an instance attribute for cache
def __init__(self,*args, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion app/static/js/bonnerManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function downloadSpreadsheet(blob, fileName) {
function addSearchCapabilities(inputElement){
$(inputElement).on("input", function(){
let year = $(this).data('year');
searchUser(this.id, student => cohortRequest(year, "add", student.username), false, null, "student");
searchUser(this.id, student => cohortRequest(year, "add", student.username), false, false, null, "student");
});
}

Expand Down
2 changes: 1 addition & 1 deletion app/static/js/createEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ function handleTimeFormatting(timeArray){
}

$("#eventFacilitator").on('input', function () {
searchUser("eventFacilitator", callback, true, undefined, "instructor");
searchUser("eventFacilitator", callback, false, true, undefined, "instructor");
});

$("#facilitatorTable").on("click", "#remove", function () {
Expand Down
2 changes: 1 addition & 1 deletion app/static/js/manageVolunteers.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ $(document).ready(function() {
});

$("#addVolunteerInput").on("input", function() {
searchUser("addVolunteerInput", callback, true, "addVolunteerModal");
searchUser("addVolunteerInput", callback, false, true, "addVolunteerModal");
});


Expand Down
2 changes: 1 addition & 1 deletion app/static/js/minorAdminPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,6 @@ $("#addInterestedStudentsModal").on("shown.bs.modal", function() {
});

$("#addStudentInput").on("input", function() {
searchUser("addStudentInput", callback, true, "addInterestedStudentsModal");
searchUser("addStudentInput", callback, false, true, "addInterestedStudentsModal");
});

2 changes: 1 addition & 1 deletion app/static/js/searchStudent.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ function callback(selected) {
}
$(document).ready(function() {
$("#searchStudentsInput").on("input", function() {
searchUser("searchStudentsInput", callback);
searchUser("searchStudentsInput", callback, true);
});

$("#searchIcon").click(function (e) {
Expand Down
11 changes: 9 additions & 2 deletions app/static/js/searchUser.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
export default function searchUser(inputId, callback, clear=false, parentElementId=null, category = null)
export default function searchUser(
inputId,
callback,
alwaysShowGraduatedStudents=false,
clear=false,
parentElementId=null,
category=null,
)
{
var query = $(`#${inputId}`).val()
let columnDict = {};
Expand All @@ -10,7 +17,7 @@ export default function searchUser(inputId, callback, clear=false, parentElement
url: `/searchUser/${query}`,
type: "GET",
dataType: "json",
data:{"category":category},
data:{"category":category, "alwaysShowGraduatedStudents": alwaysShowGraduatedStudents ? 1 : 0},
success: function(searchResults) {
response(Object.entries(searchResults).map( (item) => {
return {
Expand Down
2 changes: 1 addition & 1 deletion app/static/js/slcManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ $(document).ready(function() {
});

$("#courseInstructor").on('input', function() {
searchUser("courseInstructor", createNewRow, true, null, "instructor");
searchUser("courseInstructor", createNewRow, false, true, null, "instructor");
setTimeout(function() {
$(".ui-autocomplete").css("z-index", 9999);
}, 500);
Expand Down
2 changes: 1 addition & 1 deletion app/static/js/slcNewProposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ $(document).ready(function(e) {
})

$("#courseInstructor").on('input', function() {
searchUser("courseInstructor", createNewRow, true, null, "instructor");
searchUser("courseInstructor", createNewRow, false, true, null, "instructor");
});

$("#courseInstructor").popover({
Expand Down
6 changes: 3 additions & 3 deletions app/static/js/userManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ function callbackProgramManager(selected, action = 'add') {
$(document).ready(function(){
// Admin Management
$("#searchCeltsAdminInput").on("input", function(){
searchUser("searchCeltsAdminInput", callbackAdmin, false, null, "celtsLinkAdmin")
searchUser("searchCeltsAdminInput", callbackAdmin, false, false, null, "celtsLinkAdmin")
});
$("#searchCeltsStudentStaffInput").on("input", function(){
searchUser("searchCeltsStudentStaffInput", callbackStudentStaff, false, null, "student")
searchUser("searchCeltsStudentStaffInput", callbackStudentStaff, false, false, null, "student")
});
$("#searchProgramManagersInput").on("input", function() {
searchUser("searchProgramManagersInput", callbackProgramManager, true, "parentManager", "all");
searchUser("searchProgramManagersInput", callbackProgramManager, false, true, "parentManager", "all");
});
$("#addNewTerm").on("click",function(){
addNewTerm();
Expand Down
21 changes: 21 additions & 0 deletions app/static/js/userProfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ $(document).ready(function(){
});
});

$('#hideGraduatedStudents').click(function() {
let checked = $(this).is(":checked")
var username = $(this).data('username');
$.ajax({
data: {checked: checked ? 1 : 0},
method: "POST",
url: `/admin/hideGraduatedStudents/${username}`,
success: function(response) {
if (checked == true) {
msgFlash(`Graduated students hidden on CELTS Link for ${username}.`, "success", 1000)
} else {
msgFlash(`Graduated students shown on CELTS Link for ${username}.`, "success", 1000)
}
},
error: function(request, status, error) {
console.error("Error hiding graduated students:", error);
msgFlash(`Error hiding graduated students for ${username}.`)
}
});
})

$('.onTranscriptCheckbox').click(function() {
var onTranscript = $(this).is(':checked');
var username = $(this).data('username');
Expand Down
39 changes: 26 additions & 13 deletions app/templates/main/userProfile.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,32 @@ <h1>{{volunteer.firstName}} {{volunteer.lastName}}</h1>
</div>
{%endif%}
</div>
</div>
<div class="profile-links">
<a class="btn btn-warning btn-sm" role="button" data-bs-toggle="modal" data-bs-target="#editVolunteerModal">Edit Volunteer Information</a>

{% if volunteer == g.current_user or g.current_user.isCeltsAdmin %}
<a href="/profile/{{volunteer.username}}/travelForm" class="btn btn-primary btn-sm" target="_blank">Print Travel Form</a>
{% endif %}

<a href="/profile/{{volunteer.username}}/serviceTranscript" class="btn btn-primary btn-sm">View Service Transcript</a>

{% if volunteer.minorInterest %}
<a href="/profile/{{volunteer.username}}/cceMinor" class="btn btn-primary btn-sm">Manage CCE Minor</a>
{% endif %}

<div class="row pb-2 pe-0">
<div class="col"></div>
<div class="col-auto pe-0 ">
{% if (volunteer == g.current_user) and (not g.current_user.isStudent) %}
<div class="form-check form-switch">
<label class="custom-control-label" for='hideGraduatedStudents'><strong>Globally hide graduated students</strong></label>
<input class="form-check-input" data-username="{{volunteer.username}}" type="checkbox" {% if volunteer.hideGraduatedStudents %} checked {% endif %} id="hideGraduatedStudents" name="hideGraduatedStudents"/>
</div>
{% endif %}
<select data-username="{{volunteer.username}}" id="actions" class="form-select" align="right">
<option value="" selected disabled hidden>Choose an Action</option>
{% if volunteer == g.current_user or g.current_user.isCeltsAdmin %}
<option value="Emergency Contact"> {{'Edit' if volunteer == g.current_user else 'View'}} Emergency Contact </option>
<option value="Insurance Information"> {{'Edit' if volunteer == g.current_user else 'View'}} Insurance Information </option>
{% endif %}
{% if g.current_user.isAdmin %}
<option value="Manage CCE Minor"> Manage CCE Minor </option>
{% endif %}
{% if volunteer == g.current_user or g.current_user.isCeltsAdmin %}
<option value="Print Travel Form"> Print Travel Form </option>
{% endif %}
<option value="View Service Transcript"> View Service Transcript </option>
</select>
</div>
</div>
</div>

<div class="accordion" id="userProfile">
Expand Down
Loading
Loading