Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creation of UI for Imported Courses #1111

Merged
merged 118 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 94 commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
f826365
Created the concept of Imported Courses
stevensonmichel Dec 19, 2023
3fa940d
Created modal for imported courses
stevensonmichel Dec 20, 2023
b3761ef
Embellished the modal for imported courses
stevensonmichel Dec 20, 2023
2a657fe
Updated Contributors, Michel was missing
Mercy-Eze Dec 20, 2023
86e1e2f
Added testing line for POST request
stevensonmichel Dec 21, 2023
275c71c
Working on the Modal for altering courses
Mercy-Eze Dec 21, 2023
8c50cf9
Created new File for instructor Table purpose
stevensonmichel Dec 21, 2023
e4aeeda
Created tabs for Native Courses (Approved and Unapproved courses) and…
stevensonmichel Dec 22, 2023
db546bb
Fixed buttons in Service Learning Faculty sections that were blocking…
stevensonmichel Dec 22, 2023
e39341a
Modified data in the database based on modifications inside modal for…
stevensonmichel Dec 22, 2023
7170bae
Created Javascript function to get data when imported course modal is…
stevensonmichel Dec 22, 2023
b55bd8b
Successfully loaded information on Imported Courses modal using GET r…
stevensonmichel Dec 22, 2023
e5978e7
Imported instructorTable.js file in html and created field for instru…
stevensonmichel Dec 25, 2023
5e09d6f
Resolved Merge Conflict
Mercy-Eze Dec 25, 2023
6d09b26
Removed redundant Imported Courses from page
Mercy-Eze Dec 25, 2023
f58a166
Removed duplicate code
Mercy-Eze Dec 25, 2023
caba439
Exported autocomplete data for suggestions, but data is still not vis…
stevensonmichel Dec 25, 2023
0f297f1
Merge branch 'CreateCourseParticipantUI_#1059' of github.com:BCStuden…
stevensonmichel Dec 25, 2023
d44bd25
Rearrange imported courses:
stevensonmichel Dec 25, 2023
387114e
Implemented new ways of importing data in the backend
stevensonmichel Dec 26, 2023
eb54414
Testing the autocomplete as well as backend changes
stevensonmichel Dec 27, 2023
2064196
Fixed Long Term Issue of Displaying Autocomplete Dropdown of Instruct…
Mercy-Eze Dec 28, 2023
7cbfec5
Comment added
Mercy-Eze Dec 29, 2023
11ad624
Merge branch 'CreateCourseParticipantUI_#1059' of github.com:BCStuden…
stevensonmichel Dec 29, 2023
4860728
Fixed merge conflict
stevensonmichel Dec 29, 2023
3d1abad
Fixed input mask issues
stevensonmichel Dec 29, 2023
daba737
Successfully update course information in the database. Started worki…
stevensonmichel Dec 29, 2023
270f119
Fixed remove button inside imported courses modal
stevensonmichel Jan 1, 2024
088947f
Import instructors to be displayed on the modal if edit is clicked
stevensonmichel Jan 1, 2024
521b3c1
Testing data on the backend and the frontend
stevensonmichel Jan 1, 2024
cf476d3
Fixing the problem with adding or not adding instructors in imported …
stevensonmichel Jan 1, 2024
b240783
Fixed Remove functionality as well as Getting input data in imported …
stevensonmichel Jan 2, 2024
0f7abe2
Still working on catching removed instructors
stevensonmichel Jan 2, 2024
b9330bf
Implemented saveCourseData function for imported courses
stevensonmichel Jan 3, 2024
8bf416a
Fixed remove from first instance of adding instructors
stevensonmichel Jan 4, 2024
1a70dbd
Same changes
stevensonmichel Jan 4, 2024
ccb5ed0
Clear up instructor table in the modal prior to populate course data …
stevensonmichel Jan 4, 2024
5ec1b48
Fixed remove button
stevensonmichel Jan 4, 2024
7213d37
Merge branch 'development' into CreateCourseParticipantUI_#1059
AndersonStettner Jan 4, 2024
71347bd
Created tests for imported course in test_course_management.py file
stevensonmichel Jan 4, 2024
88bee68
Merge branch 'CreateCourseParticipantUI_#1059' of github.com:BCStuden…
stevensonmichel Jan 4, 2024
bcc9e8d
Omitted codes about testing imported courses
stevensonmichel Jan 4, 2024
914705a
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Jan 4, 2024
c33013a
Fixed Adding/Removing instructors functionality in Imported Courses m…
stevensonmichel Jan 4, 2024
1a989ba
Cleaned files and added comments and docstrings
stevensonmichel Jan 5, 2024
a5a43b7
Deleted testing console.log lines
stevensonmichel Jan 5, 2024
5044598
Erase testing lines in the code
stevensonmichel Jan 17, 2024
d29df16
Cleaned code by removing testing lines and adding comments when neces…
stevensonmichel Jan 17, 2024
5b85976
Fixed docstrings describing purpose of editimportedcourses function
stevensonmichel Jan 18, 2024
93ee8f6
Update hours earned on modal to reflect service hours earned for a pa…
stevensonmichel Jan 22, 2024
4afdd32
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Jan 22, 2024
be1af72
Included meaningful variable names for instructors
stevensonmichel Jan 22, 2024
fd5fdb3
Add constraints for the input of hours earned in imported courses mod…
stevensonmichel Jan 22, 2024
8e9dca3
Change alter value name into modify for more clarity
stevensonmichel Jan 22, 2024
3c131fd
Fixed query formatting
stevensonmichel Jan 29, 2024
55517a3
Fixed title in the modal
stevensonmichel Jan 29, 2024
c05bf0d
Customized modal title based on selected imported course
stevensonmichel Jan 30, 2024
194da5f
Fixed redirect after submitting info for imported courses
stevensonmichel Feb 2, 2024
2b79141
Fixed instructors saved for other courses
stevensonmichel Feb 5, 2024
2e0a7a5
Fixed remove button and rename ids for modals
stevensonmichel Feb 7, 2024
faf6a7b
Merge branch 'development' into CreateCourseParticipantUI_#1059
andersoncedu Feb 8, 2024
3553656
Removed instructor table js and commented code.
andersoncedu Feb 8, 2024
f08b2e9
Made formatting changes, removed unecessary id's from manageservicele…
andersoncedu Feb 8, 2024
f687629
Removed term from route and redirect to correct tab on page when alte…
andersoncedu Feb 12, 2024
f3c6f25
Removed script tag that wasnt doing anything.
andersoncedu Feb 12, 2024
0e84618
Removed 'attachments' from exitImportedCourses.
andersoncedu Feb 12, 2024
9b358f4
Removed unnecessary lines and printing statements
stevensonmichel Feb 14, 2024
ad8419a
Cleaned code and provide comments in some sections
stevensonmichel Feb 14, 2024
34d7c84
Reformat comments
stevensonmichel Feb 19, 2024
d841abd
Merge branch 'development' of github.com:BCStudentSoftwareDevTeam/cel…
AndersonStettner Feb 20, 2024
d7e29aa
changed formatting on a query
AndersonStettner Feb 20, 2024
72cbdc8
Fixed exception raised if course if not found
stevensonmichel Feb 20, 2024
aed8226
made Import Courses button always show and changed error messaging fo…
AndersonStettner Feb 22, 2024
369cadd
small formatting changes
AndersonStettner Feb 22, 2024
6ced29e
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Mar 4, 2024
edf21cc
Created instructor table module
stevensonmichel Mar 5, 2024
61f052f
Modified modal handling of instructors
stevensonmichel Mar 5, 2024
9c7268f
Set up imported functions from files
stevensonmichel Mar 6, 2024
a2f4339
Make use of external functions for new proposals
stevensonmichel Mar 6, 2024
ad35e03
Solved updating course data based on last submission
stevensonmichel Mar 6, 2024
8190325
Fixed phone number edit button
stevensonmichel Mar 7, 2024
eae0034
Fixed merge conflict
stevensonmichel Mar 15, 2024
2707b3b
Fixed input click for phone number
stevensonmichel Mar 15, 2024
04cd08b
Fix instructors' phone number in the imported courses modal
stevensonmichel Mar 18, 2024
d0cb43c
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Mar 18, 2024
60dde47
Fixed more merge conflicts
stevensonmichel Mar 18, 2024
df04d70
Fixed merge conflicts
stevensonmichel Mar 20, 2024
c9c8b3d
Solved huge merge conflict
stevensonmichel Mar 20, 2024
2f69805
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Mar 20, 2024
e521ed7
Fixed status key message and blank instructors
stevensonmichel Mar 25, 2024
a08eecd
Fixed manageTerm parameter occurrence in this branch
stevensonmichel Mar 25, 2024
a6badfc
Changed alterModal name and enhanced updateInstructorList function de…
stevensonmichel Mar 27, 2024
a40429d
Fixed comments and variable names
stevensonmichel Mar 27, 2024
f426739
Created attachInstructorsInfo function
stevensonmichel Mar 27, 2024
95e1fa5
Allowed flash message to appear in front of the Imported Courses modal
stevensonmichel Apr 3, 2024
3076291
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Apr 3, 2024
994abb5
app/templates/admin/manageServiceLearningFaculty.html
stevensonmichel Apr 4, 2024
85589e2
Added courseAbbreviation on Service Transcript if courseName is not a…
stevensonmichel Apr 8, 2024
851eb3c
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Apr 8, 2024
62d4b31
Addressed formatting issues
stevensonmichel Apr 10, 2024
0baa166
Set default service hours in case of failure to 20
stevensonmichel Apr 10, 2024
0957dc7
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Apr 10, 2024
717d8f4
changed header name
AndersonStettner Apr 11, 2024
e468338
Merge branch 'development' into CreateCourseParticipantUI_#1059
AndersonStettner Apr 11, 2024
d624553
Addressed most of the unresolved comments by Lawrence.
andersoncedu Apr 11, 2024
5808fc4
Addressed Lawrence's final comment.
andersoncedu Apr 11, 2024
f19c8a3
Changed some variable name to be mroe consistent.
andersoncedu Apr 11, 2024
89e9fba
Changed string concatenation to use string interpolation in many plac…
andersoncedu Apr 12, 2024
0b73261
Created test for editImportedCourses
stevensonmichel Apr 17, 2024
b0722d4
Created test for edit imported courses
stevensonmichel Apr 18, 2024
8cf2cc2
Finished test for editImportedCourses function
stevensonmichel Apr 19, 2024
ed2b92d
Merge branch 'development' into CreateCourseParticipantUI_#1059
stevensonmichel Apr 19, 2024
7b7ea91
Solved view bug
stevensonmichel Apr 24, 2024
9f1d4d4
Displayed imported courses' course abbreviation if course name is not…
stevensonmichel Apr 24, 2024
0e215fe
Removed native and imported courses tabs
stevensonmichel Apr 26, 2024
4b51626
Fixed some formatting
andersoncedu Apr 30, 2024
a261c83
Merge branch 'development' into CreateCourseParticipantUI_#1059
AndersonStettner May 6, 2024
8608074
Update manageServiceLearningFaculty.html
AndersonStettner May 7, 2024
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
1 change: 1 addition & 0 deletions app/config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ contributors:
- name: "Mercy Eze"
role: "Software Engineer"
- name: "Michel Moncada"
role: "Software Engineer"
- name: "Stevenson Michel"
role: "Software Engineer"
- name: "Lawrence Hoerst"
Expand Down
67 changes: 64 additions & 3 deletions app/controllers/admin/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from app.models.eventRsvp import EventRsvp
from app.models.eventParticipant import EventParticipant
from app.models.user import User
from app.models.course import Course
from app.models.courseInstructor import CourseInstructor
from app.models.courseParticipant import CourseParticipant
from app.models.eventTemplate import EventTemplate
from app.models.adminLog import AdminLog
from app.models.eventRsvpLog import EventRsvpLog
Expand All @@ -33,7 +36,7 @@
from app.logic.fileHandler import FileHandler
from app.logic.bonner import getBonnerCohorts, makeBonnerXls, rsvpForBonnerCohort
from app.controllers.admin import admin_bp
from app.logic.serviceLearningCourses import parseUploadedFile, saveCourseParticipantsToDatabase, unapprovedCourses, approvedCourses, getInstructorCourses
from app.logic.serviceLearningCourses import parseUploadedFile, saveCourseParticipantsToDatabase, unapprovedCourses, approvedCourses, importedCourses, getInstructorCourses, editImportedCourses



Expand Down Expand Up @@ -339,6 +342,7 @@ def deleteRoute(eventId):
except Exception as e:
print('Error while canceling event:', e)
return "", 500

@admin_bp.route('/event/<eventId>/deleteEventAndAllFollowing', methods=['POST'])
def deleteEventAndAllFollowingRoute(eventId):
try:
Expand All @@ -349,6 +353,7 @@ def deleteEventAndAllFollowingRoute(eventId):
except Exception as e:
print('Error while canceling event:', e)
return "", 500

@admin_bp.route('/event/<eventId>/deleteAllRecurring', methods=['POST'])
def deleteAllRecurringEventsRoute(eventId):
try:
Expand Down Expand Up @@ -418,6 +423,7 @@ def addCourseFile():
@admin_bp.route('/manageServiceLearning', methods = ['GET', 'POST'])
@admin_bp.route('/manageServiceLearning/<term>', methods = ['GET', 'POST'])
def manageServiceLearningCourses(term=None):

"""
The SLC management page for admins
"""
Expand All @@ -432,16 +438,35 @@ def manageServiceLearningCourses(term=None):
manageTerm = Term.get_or_none(Term.id == term) or g.current_term

setRedirectTarget(request.full_path)

# retrieve and store the courseID of the imported course from a session variable if it exists.
# This allows us to export the courseID in the html and use it.
courseID = session.get("alterCourseId")

if courseID:
# delete courseID from the session if it was retrieved, for storage purposes.
session.pop("alterCourseId")
return render_template('/admin/manageServiceLearningFaculty.html',
courseInstructors = getInstructorCourses(),
unapprovedCourses = unapprovedCourses(manageTerm),
approvedCourses = approvedCourses(manageTerm),
importedCourses = importedCourses(manageTerm),
terms = selectSurroundingTerms(g.current_term),
term = manageTerm,
cpPreview= session.get('cpPreview',{}),
stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved
cpPreviewErrors = session.get('cpErrors',[]),
courseID = courseID
)

return render_template('/admin/manageServiceLearningFaculty.html',
courseInstructors = getInstructorCourses(),
unapprovedCourses = unapprovedCourses(manageTerm),
approvedCourses = approvedCourses(manageTerm),
importedCourses = importedCourses(manageTerm),
terms = selectSurroundingTerms(g.current_term),
term = manageTerm,
cpPreview= session.get('cpPreview',{}),
cpPreviewErrors = session.get('cpErrors',[])
)
)

@admin_bp.route("/deleteUploadedFile", methods= ["POST"])
def removeFromSession():
Expand All @@ -452,6 +477,42 @@ def removeFromSession():

return ""

@admin_bp.route('/manageServiceLearning/imported/<courseID>', methods = ['POST', 'GET'])
@admin_bp.route('/manageServiceLearning/imported/<courseID>', methods = ['POST'])
stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved
def alterImportedCourse(courseID):
"""
This route handles a GET and a POST request for the purpose of imported courses.
The GET request provides preexisting information of an imported course in a modal.
The POST request updates a specific imported course (course name, course abbreviation,
hours earned on completion, list of instructors) in the database with new information
coming from the imported courses modal.
"""
if request.method == 'GET':
try:
targetCourse = Course.get_by_id(courseID)

targetInstructors = CourseInstructor.select().where(CourseInstructor.course == targetCourse)
stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved
serviceHours = list(CourseParticipant.select().where(CourseParticipant.course_id == targetCourse.id))[0].hoursEarned
stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved

courseData = model_to_dict(targetCourse, recurse=False)
courseData['instructors'] = [model_to_dict(instructor.user) for instructor in targetInstructors]
courseData["hoursEarned"] = serviceHours
stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved

stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved
return jsonify(courseData)

except DoesNotExist:
flash("Course not found")
return jsonify({"error": "Course not found"}), 404

if request.method == 'POST':
# Update course information in the database
courseData = request.form.copy()
editImportedCourses(courseData)
session['alterCourseId'] = courseID

return redirect(url_for("admin.manageServiceLearningCourses", term=courseData['termId']))


@admin_bp.route("/manageBonner")
def manageBonner():
if not g.current_user.isCeltsAdmin:
Expand Down
49 changes: 49 additions & 0 deletions app/logic/serviceLearningCourses.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ def approvedCourses(termId: int) -> List[Course]:

return approvedCourses

def importedCourses(termId: int) -> List[Course]:
andersoncedu marked this conversation as resolved.
Show resolved Hide resolved
"""
Queries the database to get all the necessary information for
imported courses.
"""
importedCourses: List[Course] = list(Course.select(Course, Term, CourseStatus, fn.GROUP_CONCAT(" " ,User.firstName, " ", User.lastName).alias('instructors'))
.join(CourseInstructor, JOIN.LEFT_OUTER)
.join(User, JOIN.LEFT_OUTER).switch(Course)
.join(CourseStatus).switch(Course)
.join(Term)
.where(Term.id == termId, Course.status == CourseStatus.IMPORTED)
.group_by(Course, Term, CourseStatus))

return importedCourses

def getInstructorCourses() -> Dict[User, str]:
"""
This function queries all of the course instructors and their classes and maps
Expand Down Expand Up @@ -251,6 +266,40 @@ def updateCourse(courseData, attachments=None) -> Union[Course, bool]:
transaction.rollback()
return False

def editImportedCourses(courseData):
"""
This function will take in courseData for the SLC proposal page and a dictionary
of instructors assigned to the imported course after that one is edited
and update the information in the db.
"""

with mainDB.atomic() as transaction:
try:
course = Course.get_by_id(courseData["courseId"])

Course.update(courseName=courseData["courseName"]).where(Course.id == course.id).execute()

(CourseParticipant.update(hoursEarned=courseData["hoursEarned"])
.where(CourseParticipant.course_id == course.id).execute())

instructorList = []
CourseInstructor.delete().where(CourseInstructor.course == course).execute()

if 'instructor[]' in courseData:
instructorList = courseData.getlist('instructor[]')

for instructor in instructorList:
# Checks that empty string is not added as a course instructor because some keys in the dictionary are empty string.
if instructor:
CourseInstructor.create(course=course, user=instructor)

return Course.get_by_id(course.id)

except Exception as e:
print(e)
transaction.rollback()
return False

########### Course Actions ###########

def parseUploadedFile(filePath):
Expand Down
51 changes: 51 additions & 0 deletions app/static/js/instructorTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Instructor manipulation functions
// -------------------------------------

export function getRowUsername(element) {
return $(element).closest("tr").data("username")
}

export function createNewRow(selectedInstructor) {
let instructor = (selectedInstructor["firstName"]+" "+selectedInstructor["lastName"]+" ("+selectedInstructor["email"]+")");
andersoncedu marked this conversation as resolved.
Show resolved Hide resolved
let username = selectedInstructor["username"];
let phone = selectedInstructor["phoneNumber"];
let tableBody = $("#instructorTable").find("tbody");

if(tableBody.prop('outerHTML').includes(instructor)){
msgFlash("Instructor is already added.", "danger");
stevensonmichel marked this conversation as resolved.
Show resolved Hide resolved
return;
}
// Create new table row and update necessary attributes
let lastRow = tableBody.find("tr:last");
let newRow = lastRow.clone();

let instructorName = newRow.find("td:eq(0) p")
instructorName.text(instructor);

let phoneInput = newRow.find("td:eq(0) input")
phoneInput.val(phone);
phoneInput.attr("id", "inputPhoneNumber-" +username);
$(phoneInput).inputmask('(999)-999-9999');

let removeButton = newRow.find("td:eq(1) button")
let editLink = newRow.find("td:eq(0) a")
editLink.attr("id", "editButton-" + username);

editLink.attr("data-username", username)
newRow.prop("hidden", false);
lastRow.after(newRow);

phoneInput.attr("data-value", phone)
andersoncedu marked this conversation as resolved.
Show resolved Hide resolved
var edit = "#editButton-" + username
var input = "#inputPhoneNumber-" + username
if (username){
setupPhoneNumber(edit, input)
andersoncedu marked this conversation as resolved.
Show resolved Hide resolved
}

$("#instructorTableNames").append('<input hidden name="instructor[]" value="' + username + '"/>')
andersoncedu marked this conversation as resolved.
Show resolved Hide resolved
}

export function getCourseInstructors() {
// get usernames out of the table rows into an array
return $("#instructorTableNames input").map((i,el) => $(el).val())
}
14 changes: 8 additions & 6 deletions app/static/js/manageServiceLearningFaculty.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@


$(document).ready( function () {

/******** Faculty Table Management **************/
/************** Faculty Table Management **************/
var table = $('#SLCFacultyTable').DataTable({
"fnDrawCallback": function(oSettings) {
$('.dataTables_length').hide();
Expand Down Expand Up @@ -37,12 +39,12 @@ $(document).ready( function () {
});


/******** Preview Events **************/
$('#modalPreview button[data-bs-dismiss="modal"]').click(function () {
$('#modalPreview').removeClass('show d-block');
/************** Preview Events **************/
$('#previewImportedCourses button[data-bs-dismiss="modal"]').click(function () {
$('#previewImportedCourses').removeClass('show d-block');
});

$('#modalSubmit').on('hidden.bs.modal', function () {
$('#submitImportedCourses').on('hidden.bs.modal', function () {
$('#addCourseParticipant').val('');
})

Expand All @@ -64,7 +66,7 @@ $(document).ready( function () {

/************** Course Participant Logic **************/
$("#modalCourseParticipant").on("click", function () {
$("#modalSubmit").modal("toggle");
$("#submitImportedCourses").modal("toggle");
});

$('#closeAddCourseParticipants').on('click', function () {
Expand Down
Loading
Loading