From 26026653c07a5c2b73cf45af44091db3850e79c4 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 13 Mar 2024 10:12:37 -0400 Subject: [PATCH 001/473] Removed spreadsheet ui from this branch. --- app/controllers/admin/__init__.py | 1 - app/templates/admin/spreadsheetMaker.html | 23 ----------------------- app/templates/sidebar.html | 3 --- 3 files changed, 27 deletions(-) delete mode 100644 app/templates/admin/spreadsheetMaker.html diff --git a/app/controllers/admin/__init__.py b/app/controllers/admin/__init__.py index f3030c43a..375c695bd 100644 --- a/app/controllers/admin/__init__.py +++ b/app/controllers/admin/__init__.py @@ -10,6 +10,5 @@ from app.controllers.admin import routes from app.controllers.admin import userManagement from app.controllers.admin import volunteers -from app.controllers.admin import stats from app.controllers.admin import minor diff --git a/app/templates/admin/spreadsheetMaker.html b/app/templates/admin/spreadsheetMaker.html deleted file mode 100644 index 18266ddfe..000000000 --- a/app/templates/admin/spreadsheetMaker.html +++ /dev/null @@ -1,23 +0,0 @@ -{% set title = "Admin Logs" %} -{% extends "base.html" %} - -{% block scripts %} - {{super()}} - - - {% block styles %} - {{super()}} - {% endblock %} -{% endblock %} -{% block app_content %} - - - - - -{% endblock %} diff --git a/app/templates/sidebar.html b/app/templates/sidebar.html index 6df27415e..93da61844 100644 --- a/app/templates/sidebar.html +++ b/app/templates/sidebar.html @@ -68,9 +68,6 @@ Bonner Management - - Create Spreadsheet - Minor Management From 8c48885a358def8e7c4340388e93e6ce298885c5 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 13 Mar 2024 10:14:35 -0400 Subject: [PATCH 002/473] Removed stats.py --- app/controllers/admin/stats.py | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 app/controllers/admin/stats.py diff --git a/app/controllers/admin/stats.py b/app/controllers/admin/stats.py deleted file mode 100644 index 30e5e7cec..000000000 --- a/app/controllers/admin/stats.py +++ /dev/null @@ -1,29 +0,0 @@ -from flask import abort, render_template, g, request -from app.controllers.admin import admin_bp - -from app.models.term import Term - -from app.logic.spreadsheet import create_spreadsheet - -@admin_bp.route("/spreadsheetMaker") -def spreadsheetMaker(): - if not g.current_user.isCeltsAdmin: - abort(403) - - academicYears = [] - allTerms = list(Term.select().order_by(Term.id)) - for term in allTerms: - if term.academicYear not in academicYears: - academicYears.append(term.academicYear) - - return render_template("/admin/spreadsheetMaker.html", - academicYears = academicYears) - -@admin_bp.route("/createSpreadsheet/", methods=["POST"]) -def createSpreadsheet(): - if not g.current_user.isCeltsAdmin: - abort(403) - - formData = request.form - print(formData.get("academicYear")) - return "" \ No newline at end of file From 539bc9857a6da1eed86eda6b5a2f2e20ff87f980 Mon Sep 17 00:00:00 2001 From: ndiayem Date: Mon, 10 Jun 2024 19:23:16 +0000 Subject: [PATCH 003/473] Testing to see --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51dee0add..ffb1e47b4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ * Mac OS or Linux * mysql ```root``` user is accessible by a non-root OS user, with password ```root``` (in order to run ```reset_database.sh```) * default python is Python 3 - + ## Getting Started With CELTS in a devcontainer 1. If on Windows 10, make sure your Windows install is in developer mode so that core.symlinks will be set properly: https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development (requires admin privileges) 3. Set up an SSH agent with your GitHub SSH key. https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent From 9a2c2bdd1b63e9bee85110ee3e55af5047f1ba12 Mon Sep 17 00:00:00 2001 From: ndiayem Date: Tue, 11 Jun 2024 14:31:43 +0000 Subject: [PATCH 004/473] I added my name to the contributors list --- app/config/default.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/config/default.yml b/app/config/default.yml index cae83b605..7dbdc558a 100644 --- a/app/config/default.yml +++ b/app/config/default.yml @@ -120,3 +120,5 @@ contributors: role: "Software Engineer" - name: "Chris Anderson" role: "Software Engineer" + - name: "Moustapha Ndiaye" + role: "Software Engineer" \ No newline at end of file From 17532ea551d3d2e3395055b3d8aab000abc0d5d8 Mon Sep 17 00:00:00 2001 From: ndiayem Date: Tue, 11 Jun 2024 20:50:20 +0000 Subject: [PATCH 005/473] We fixed issue #1158: Added an uncheck button to allow users to uncheck selected image attachments. --- app/templates/displayFilesMacro.html | 63 +++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/app/templates/displayFilesMacro.html b/app/templates/displayFilesMacro.html index e8af00dd0..8701683f0 100644 --- a/app/templates/displayFilesMacro.html +++ b/app/templates/displayFilesMacro.html @@ -1,6 +1,6 @@ {% macro displayFiles(filePaths, titleName, deleteLink, databaseId) %} - + +
+ + + + + {% for key, value in filePaths.items() %} + + + + + + {% endfor %}
Display{{ titleName }}
+
+
+
+ +
+
+
+
+ {% set idx = key.index("/") %} + {% set fileName = key[idx+1:] %} + {% set shortName = fileName[:8] + "..." + fileName[-10:] if fileName|length > 25 else fileName %} + {{ shortName }} + + +
+ + + + + + + {% endmacro %} \ No newline at end of file From e1346c470e0ef2a87bd52bde85af9c07335b8197 Mon Sep 17 00:00:00 2001 From: ndiayem Date: Wed, 12 Jun 2024 19:54:01 +0000 Subject: [PATCH 006/473] We added a function to the script which allows users to check and uncheck selected file attachments --- app/static/js/displayFilesMacro.js | 12 ++++++++++-- app/templates/displayFilesMacro.html | 27 ++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/static/js/displayFilesMacro.js b/app/static/js/displayFilesMacro.js index 336fcf11b..7ba0c919a 100644 --- a/app/static/js/displayFilesMacro.js +++ b/app/static/js/displayFilesMacro.js @@ -21,10 +21,18 @@ $(document).ready(function(){ }); $('.attachmentCheck').change(function() { + // Store the current checkbox state + var isChecked = $(this).is(':checked'); + // Uncheck all checkboxes $('.attachmentCheck').prop('checked', false); - // Check the selected checkbox - $(this).prop('checked', true); + + // If the current checkbox was previously unchecked, check it + if (!isChecked) { + $(this).prop('checked', true); + } else { + $(this).prop('checked', false); + } var attachmentId = $(this).data('id'); var isChecked = $(this).is(':checked'); diff --git a/app/templates/displayFilesMacro.html b/app/templates/displayFilesMacro.html index 8701683f0..c174afa75 100644 --- a/app/templates/displayFilesMacro.html +++ b/app/templates/displayFilesMacro.html @@ -76,27 +76,28 @@ {% endfor %} - - - + + function uncheckAllExcept(current) { + document.querySelectorAll('.attachmentCheck').forEach(checkbox => { + if (checkbox !== current) { + checkbox.checked = false; + } + }); + } {% endmacro %} \ No newline at end of file From f1149c8345449385f6b8ccabaf6e121b2dadfafc Mon Sep 17 00:00:00 2001 From: ramazanim Date: Thu, 13 Jun 2024 15:32:34 +0000 Subject: [PATCH 007/473] added graduation-flag branch --- app/templates/admin/cceMinor.html | 6 +++++- app/templates/eventNav.html | 8 ++++---- app/templates/eventView.html | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/templates/admin/cceMinor.html b/app/templates/admin/cceMinor.html index 1f46ed4b7..d462b7fe0 100644 --- a/app/templates/admin/cceMinor.html +++ b/app/templates/admin/cceMinor.html @@ -28,7 +28,11 @@

CCE Minor Progress

{% for student in sustainedEngagement %} - {{ student.firstName }} {{ student.lastName }} + {{ student.firstName }} {{ student.lastName }} + + + + {{ student.engagementCount }}/4 {{ student.hasSummer }} diff --git a/app/templates/eventNav.html b/app/templates/eventNav.html index 6f92cceda..a271349c5 100644 --- a/app/templates/eventNav.html +++ b/app/templates/eventNav.html @@ -18,12 +18,12 @@ {% if g.current_user.isAdmin %} {{ eventheader(page_title, event, 'large', isNewEvent) }} {% endif %} - {% set alertClass = "alert-danger" if eventPast else "alert-warning"%} - {% set display = "" if eventPast or event.isCanceled else "d-none"%} + {% set alertClass = "alert-danger" if isEventPast else "alert-warning"%} + {% set display = "" if isEventPast or event.isCanceled else "d-none"%} + + {% if 'program' in eventData and eventData['program'].isBonnerScholars %}
From 0b6552fe07dfbc1b5333013c9db6408f38222a11 Mon Sep 17 00:00:00 2001 From: CollegeStevenLN <156225590+CollegeStevenLN@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:37:37 +0000 Subject: [PATCH 070/473] successfullly created a conditional to delete empty database rows on canceled proposal --- app/controllers/serviceLearning/routes.py | 8 +++++--- app/static/js/slcNewProposal.js | 9 +++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/serviceLearning/routes.py b/app/controllers/serviceLearning/routes.py index e6807060d..724583ad9 100644 --- a/app/controllers/serviceLearning/routes.py +++ b/app/controllers/serviceLearning/routes.py @@ -92,9 +92,11 @@ def slcCreateCourse(): @serviceLearning_bp.route('/serviceLearning/canceledProposal', methods=['POST']) def slcCancelProposal(): courseID = request.form.get('courseID') - print('##########################################', courseID, '##########################################') - - return 0 + course = Course.get_by_id(courseID) + if not course.courseName and not course.courseAbbreviation: + CourseQuestion.delete().where(CourseQuestion.course_id == courseID).execute() + course.delete_instance() + return "Proposal Canceled" @serviceLearning_bp.route('/serviceLearning/exit', methods=['GET']) diff --git a/app/static/js/slcNewProposal.js b/app/static/js/slcNewProposal.js index 068962792..1b3f711d1 100644 --- a/app/static/js/slcNewProposal.js +++ b/app/static/js/slcNewProposal.js @@ -83,17 +83,14 @@ $(document).ready(function(e) { method: 'POST', data: {courseID : document.getElementById('courseID').value}, success: function(response) { - alert('Successfully canceled the proposal') - msgToast("Proposal Canceled ", "Successfully canceled the proposal edit/creation.") + msgToast("Proposal Canceled", "Successfully canceled the proposal edit/creation.") }, error: function(error) { - alert('Didnt successfully canceled the proposal :(') - msgFlash(error) - console.log(error) + msgFlash('Error: ', error) } }); - // window.location.replace($(this).val()); + window.location.replace($(this).val()); }); $("#saveContinue").on("click", function() { From 76be4450877a92bd3343c4a4dfdfc0db7f1d7d5b Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Wed, 26 Jun 2024 15:28:37 +0000 Subject: [PATCH 071/473] custom toggle fixed --- app/static/js/createEvents.js | 46 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index a251771ed..e3f8c001c 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -63,12 +63,18 @@ function format24to12HourTime(timeStr){ } - var save_button = document.getElementById('submitParticipant') - + var save_button = document.getElementById('submitParticipant'); + var modal = document.getElementById('modalCustom'); + save_button.addEventListener('click', function() { // Call the function storingCustomEventAttributes() when the button is clicked storingCustomEventAttributes(); + + // Remove the modal and overlay from the DOM + $('#modalCustom').modal('hide'); + }); + let entries = [] function storingCustomEventAttributes() { @@ -86,24 +92,24 @@ function storingCustomEventAttributes() { }); console.log(entries) - $.ajax({ - type:"POST", - url: "/makeCustomEvents", - data: entries, //get the startDate, endDate and name as a dictionary - success: function(jsonData){ - var customEvents = JSON.parse(jsonData) - var customTable = $("#customEventsTable") - $("#customEventsTable tbody tr").remove(); - - for (var event of customEvents){ - var eventdate = new Date(event.date).toLocaleDateString() - recurringTable.append(""+event.name+""+eventdate+""); - } - }, - error: function(error){ - console.log(error) - } - }); + // $.ajax({ + // type:"POST", + // url: "/makeCustomEvents", + // data: entries, //get the startDate, endDate and name as a dictionary + // success: function(jsonData){ + // var customEvents = JSON.parse(jsonData) + // var customTable = $("#customEventsTable") + // $("#customEventsTable tbody tr").remove(); + + // for (var event of customEvents){ + // var eventdate = new Date(event.date).toLocaleDateString() + // recurringTable.append(""+event.name+""+eventdate+""); + // } + // }, + // error: function(error){ + // console.log(error) + // } + //}); } From 5ec1945b073e3340b66f4d837f35bdd74d84163a Mon Sep 17 00:00:00 2001 From: dea Date: Wed, 26 Jun 2024 17:04:24 +0000 Subject: [PATCH 072/473] List successfully made and it returns the correct names when called through dictionary --- app/logic/serviceLearningCourses.py | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 818c0cab9..ca43a63bf 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -60,23 +60,22 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li if 'errorMsg' in courseInfo and courseInfo['errorMsg']: print(f"Unable to save course {course}. {courseInfo['errorMsg']}") continue - - data = Course.select().where(Course.courseAbbreviation == course) - existing_Course_Info = data.dicts() - - print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@') - print(existing_Course_Info) - courseObj: Course = Course.get_or_create( - courseAbbreviation = course, - term = termObj, - defaults = {"CourseName" : "", - "sectionDesignation" : "", - "courseCredit" : "1", - "term" : termObj, - "status" : 4, - "createdBy" : g.current_user, - "serviceLearningDesignatedSections" : "", - "previouslyApprovedDescription" : "" })[0] + data = Course.select().where(Course.courseAbbreviation == course).order_by(Course.term.desc()).limit(1) + get_existing_info = list(data.dicts()) + existing_info_dict = get_existing_info[0] + print("#########################################################") + print(existing_info_dict['courseName']) + courseObj: Course = Course.create( + # courseAbbreviation = course, + # term = termObj, + defaults = {"CourseName" : existing_info_dict['courseName'], + "sectionDesignation" : "", + "courseCredit" : "1", + "term" : termObj, + "status" : 4, + "createdBy" : g.current_user, + "serviceLearningDesignatedSections" : "", + "previouslyApprovedDescription" : "" })[0] for userDict in courseInfo['students']: if userDict['errorMsg']: @@ -440,4 +439,6 @@ def parseUploadedFile(filePath): elif cellVal: # but didn't match the regex errors.append((f'ERROR: "{cellVal}" in row {cellRow} of the Excel document does not appear to be a term, course, or valid B#.',1)) + + return result, errors \ No newline at end of file From b0290626b2ef3efd126eace85543783ce5c77308 Mon Sep 17 00:00:00 2001 From: Josh Wakin Date: Wed, 26 Jun 2024 13:17:23 -0400 Subject: [PATCH 073/473] found new error after adding if else logic --- app/logic/serviceLearningCourses.py | 41 +++++++++++++++++++---------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index ca43a63bf..d12a6dc93 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -62,20 +62,33 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li continue data = Course.select().where(Course.courseAbbreviation == course).order_by(Course.term.desc()).limit(1) get_existing_info = list(data.dicts()) - existing_info_dict = get_existing_info[0] - print("#########################################################") - print(existing_info_dict['courseName']) - courseObj: Course = Course.create( - # courseAbbreviation = course, - # term = termObj, - defaults = {"CourseName" : existing_info_dict['courseName'], - "sectionDesignation" : "", - "courseCredit" : "1", - "term" : termObj, - "status" : 4, - "createdBy" : g.current_user, - "serviceLearningDesignatedSections" : "", - "previouslyApprovedDescription" : "" })[0] + + if not get_existing_info: + courseObj: Course = Course.create( + defaults = {"CourseName" : "", + "sectionDesignation" : "", + "courseCredit" : "1", + "term" : termObj, + "status" : 4, + "createdBy" : g.current_user, + "serviceLearningDesignatedSections" : "", + "previouslyApprovedDescription" : "" })[0] + + else : + existing_info_dict = get_existing_info[0] + print("#########################################################") + print(existing_info_dict['courseName']) + courseObj: Course = Course.create( + # courseAbbreviation = course, + # term = termObj, + defaults = {"CourseName" : existing_info_dict['courseName'], + "sectionDesignation" : "", + "courseCredit" : "1", + "term" : termObj, + "status" : 4, + "createdBy" : g.current_user, + "serviceLearningDesignatedSections" : "", + "previouslyApprovedDescription" : "" })[0] for userDict in courseInfo['students']: if userDict['errorMsg']: From 40fcba960e38fa07d49f286d05fd9f740784423d Mon Sep 17 00:00:00 2001 From: Josh Wakin Date: Wed, 26 Jun 2024 13:35:29 -0400 Subject: [PATCH 074/473] Modified if else statement for importing courses. --- app/logic/serviceLearningCourses.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index d12a6dc93..1c7128906 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -63,7 +63,9 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li data = Course.select().where(Course.courseAbbreviation == course).order_by(Course.term.desc()).limit(1) get_existing_info = list(data.dicts()) + if not get_existing_info: + print("############################################################################################") courseObj: Course = Course.create( defaults = {"CourseName" : "", "sectionDesignation" : "", @@ -76,7 +78,7 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li else : existing_info_dict = get_existing_info[0] - print("#########################################################") + print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") print(existing_info_dict['courseName']) courseObj: Course = Course.create( # courseAbbreviation = course, From 2c664a9fea5265444c547ad2ef700c9b60efff7a Mon Sep 17 00:00:00 2001 From: dea Date: Wed, 26 Jun 2024 17:50:58 +0000 Subject: [PATCH 075/473] List successfully made and it returns the correct names when called through dictionary --- app/logic/serviceLearningCourses.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index d12a6dc93..84c399c20 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -64,7 +64,8 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li get_existing_info = list(data.dicts()) if not get_existing_info: - courseObj: Course = Course.create( + print("########################################################") + courseObj: Course = Course.get_or_create( defaults = {"CourseName" : "", "sectionDesignation" : "", "courseCredit" : "1", @@ -78,7 +79,7 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li existing_info_dict = get_existing_info[0] print("#########################################################") print(existing_info_dict['courseName']) - courseObj: Course = Course.create( + courseObj: Course = Course.get_or_create( # courseAbbreviation = course, # term = termObj, defaults = {"CourseName" : existing_info_dict['courseName'], From 80721a757521a7bfffd8993fe82eb182ef8a8a9d Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 26 Jun 2024 20:29:33 +0000 Subject: [PATCH 076/473] fixed the toggle buttons to show custom event headings or recurring event headings based on which one is toggled --- app/static/js/createEvents.js | 105 ++++++++++++++++++++------- app/templates/admin/createEvent.html | 20 ++++- 2 files changed, 97 insertions(+), 28 deletions(-) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index e3f8c001c..b44f2c422 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -53,6 +53,7 @@ function format24to12HourTime(timeStr){ for (var event of recurringEvents){ var eventdate = new Date(event.date).toLocaleDateString() recurringTable.append(""+event.name+""+eventdate+""); + } }, error: function(error){ @@ -68,12 +69,16 @@ function format24to12HourTime(timeStr){ save_button.addEventListener('click', function() { // Call the function storingCustomEventAttributes() when the button is clicked + $("#checkIsCustom").prop('checked', true); storingCustomEventAttributes(); - + $("#checkIsCustom").prop('checked', true); // Remove the modal and overlay from the DOM $('#modalCustom').modal('hide'); }); + + + let entries = [] @@ -82,34 +87,60 @@ function storingCustomEventAttributes() { $(".extraSlots").children().each(function(index, element) { let rowData = $.map($(element).find("input"), (el) => $(el).val()); console.log("Data in row " + (index + 1) + ": " + rowData); + console.log(rowData) entries.push({ eventDate: rowData[0], startTime: rowData[1], - endTime: rowData[2] + endTime: rowData[2], + isCustom: 'true' }); + // Clear previous content + $('#displayEntries').empty(); + + // Iterate through entries array + entries.forEach(function(entry, index) { + // Create a string with entry details + let entryString = ` +

Event Date: ${entry.eventDate}

+

Start Time: ${entry.startTime}

+

End Time: ${entry.endTime}

+

Is Custom: ${entry.isCustom}

+
+ `; + + // Append entry details to displayEntries div + $('#displayEntries').append(entryString); + }); + + }); console.log(entries) - // $.ajax({ - // type:"POST", - // url: "/makeCustomEvents", - // data: entries, //get the startDate, endDate and name as a dictionary - // success: function(jsonData){ - // var customEvents = JSON.parse(jsonData) - // var customTable = $("#customEventsTable") - // $("#customEventsTable tbody tr").remove(); - - // for (var event of customEvents){ - // var eventdate = new Date(event.date).toLocaleDateString() - // recurringTable.append(""+event.name+""+eventdate+""); - // } - // }, - // error: function(error){ - // console.log(error) - // } - //}); + $.ajax({ + type:"POST", + url: "/makeCustomEvents", + data: entries, //get the startDate, endDate and name as a dictionary + success: function(jsonData){ + var customEvents = JSON.parse(jsonData) + var customTable = $("#customEventsTable") + $("#customEventsTable tbody tr").remove(); + + + + for (var event of customEvents){ + var eventdate = new Date(event.date).toLocaleDateString() + var startTime = new TimeRanges(event.startTime).String() + var endTime = new TimeRanges(event.endTime).String() + + customTable.append(""+event.name+""+eventdate+""+startTime+""+endTime+""); + } + }, + error: function(error){ + console.log(error) + } + }); } @@ -232,21 +263,24 @@ $(document).ready(function() { if (customStatus == 'on') { $('#modalCustom').modal('show');// this line pop up the modal for the custom event $('#nonCustomTime, #nonCustomDate').addClass('d-none'); // this line disappear the non custom tims and dates and replace them with recurring table div for custom events to show - $("#recurringTableDiv").removeClass('d-none'); + $("#customTableDiv").removeClass('d-none'); + $("#checkIsCustom").prop('checked', true); + } + else if (customStatus == undefined){ + $("#customTableDiv").addClass('d-none');// this line add the display none button of bootstrap so that the end-date div disappears for recurring event + } }); $(".btn-close, #cancelModalPreview").click(function(){ //this function is to untoggle the button when the modal has cancel or close button being clicked $("#checkIsCustom").prop('checked', false); $('#nonCustomTime, #nonCustomDate').removeClass('d-none'); + $("#customTableDiv").addClass('d-none'); $('.extraSlots').empty();//this line remove the added custom event slots from appearing if the custom modal is toggle again }); - - $(".customSave").click(function(){// this function doesn't work - $("#recurringTableDiv").removeClass('d-none'); - }); let counterAdd = 0 // counter to add customized ids into the newly created slots + $(".add_customevent").click(function(){ counterAdd += 1 let clonedCustom = $("#customEvent").clone();// this line clones the customEvent id div in the custom event modal on createEvent.html line 403 @@ -254,15 +288,34 @@ $(document).ready(function() { $(".extraSlots").append(clonedCustom) $("#customEvent" + counterAdd).children("div#delete_customevent").attr("id", "delete_customevent" + counterAdd) //this line finds the id delete_customevent within the parent customevent and change the id attribute $("#delete_customevent" + counterAdd).removeClass('d-none'); + + + clonedCustom.find(".delete_customevent").attr("id", "delete_customevent" + counterAdd).removeClass('d-none'); + + + deleteId.push({id: "#delete_customevent" + counterAdd}) + console.log("#delete_customevent" + counterAdd) + console.log(deleteId) + + // Attach click handler for the delete button using event delegation + $(document).on("click", "#delete_customevent" + counterAdd, function() { + // Handle delete action here + $(this).closest("#customEvent" + counterAdd).remove(); + }); + + }); + + + // $(".extraSlots").children().each(function(index, element) { // let rowData = $.map($(element).find("input"), (el) => $(el).val()) // console.log("Data in row " + (index + 1) + ": " + rowData) // // Modify this to display or manipulate your data as needed // }); - }); + diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 7ecfcd93a..58fc6bdbe 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -155,9 +155,9 @@

{{page_title}}

- + - +
{% endif %} @@ -167,9 +167,14 @@

{{page_title}}

{% if eventData.isRecurring == True and isNewEvent %} {% set hideDate = "" %} + {% set hideCustom = "d-none" %} {% elif eventData.isCustom == True and isNewEvent %} + {% set hideDate = "d-none" %} + {% set hideCustom = "" %} + {% else %} {% set hideDate = "d-none" %} + {% set hideCustom = "d-none" %} {% endif %} {{locationTimeMacro(eventData, hideDate, 'main')}} @@ -180,6 +185,13 @@

{{page_title}}

+ +
+ + + +
Event NameDateStart TimeEnd Time
+
{% if 'program' in eventData and eventData['program'].isBonnerScholars %} @@ -467,8 +479,12 @@
+ + + +
From 09dca0f884024543cc1a039f1bddd68a2c8c5f7f Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 26 Jun 2024 20:49:41 +0000 Subject: [PATCH 077/473] changed displayname function into 'createCourseDisplayName' and changed all the areas where the fucntion is used. We also changed the displayName to 'courseDisplayName' --- app/logic/serviceLearningCourses.py | 16 ++++++++++++++- .../serviceLearning/slcManagement.html | 2 +- tests/code/test_serviceLearningCourses.py | 20 +++++++++---------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 21d5acbbf..04cb8f863 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -46,12 +46,26 @@ def getSLProposalInfoForUser(user: User) -> Dict[int, Dict[str, Any]]: "creator":f"{course.createdBy.firstName} {course.createdBy.lastName}", "name": course.courseName, "abbr": course.courseAbbreviation, - "displayName": displayName(course.courseName, course.courseAbbreviation), + "courseDisplayName": createCourseDisplayName(course.courseName, course.courseAbbreviation), "faculty": faculty, "term": course.term, "status": course.status.status} return courseDict +def createCourseDisplayName(name, abbreviation): + ''' + This function combines course name and numbers with conditions + inputs: course name, course abbreviation + ''' + if name and abbreviation: + return f"{abbreviation} - {name}" + elif not name and not abbreviation: + return '' + elif not name: + return abbreviation + elif not abbreviation: + return name + def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, List[Dict[str, Any]]]]]) -> None: for term, terminfo in cpPreview.items(): termObj: Term = Term.get_or_none(description = term) or addPastTerm(term) diff --git a/app/templates/serviceLearning/slcManagement.html b/app/templates/serviceLearning/slcManagement.html index 42232a230..bf2bd689c 100644 --- a/app/templates/serviceLearning/slcManagement.html +++ b/app/templates/serviceLearning/slcManagement.html @@ -29,7 +29,7 @@

{{user.firstName}} {{user.lastName}}'s SLC Proposal {% for course in courseDict %} - {{courseDict[course]['displayName']}} + {{courseDict[course]['courseDisplayName']}} {{courseDict[course]['creator']}} {{courseDict[course]['faculty']|join(", ")}} {{courseDict[course]['term'].description}} diff --git a/tests/code/test_serviceLearningCourses.py b/tests/code/test_serviceLearningCourses.py index b289aa3eb..4bed069b4 100644 --- a/tests/code/test_serviceLearningCourses.py +++ b/tests/code/test_serviceLearningCourses.py @@ -11,7 +11,7 @@ from app.models.courseParticipant import CourseParticipant from app.logic.serviceLearningCourses import * -from app.logic.displayName import displayName + @pytest.mark.integration def test_getServiceLearningCoursesData(): @@ -23,7 +23,7 @@ def test_getServiceLearningCoursesData(): assert "Submitted" == courseDict[2]['status'] assert 'Spring 2021' in courseDict[2]['term'].description assert "Scott Heggen" == courseDict[2]['creator'] - assert "SPN 104 - Spanish Help" == courseDict[2]['displayName'] + assert "SPN 104 - Spanish Help" == courseDict[2]['courseDisplayName'] courseDict = getSLProposalInfoForUser('heggens') @@ -33,7 +33,7 @@ def test_getServiceLearningCoursesData(): assert "Approved" == courseDict[3]['status'] assert 'Summer 2021' in courseDict[3]['term'].description assert "Brian Ramsay" == courseDict[3]['creator'] - assert "FRN 103 - Frenchy Help" == courseDict[3]['displayName'] + assert "FRN 103 - Frenchy Help" == courseDict[3]['courseDisplayName'] courseDict = getSLProposalInfoForUser('heggens') @@ -43,19 +43,19 @@ def test_getServiceLearningCoursesData(): assert "In Progress" == courseDict[4]['status'] assert 'Spring 2021' in courseDict[4]['term'].description assert "Scott Heggen" == courseDict[4]['creator'] - assert "Testing" == courseDict[4]['displayName'] + assert "Testing" == courseDict[4]['courseDisplayName'] @pytest.mark.integration -def test_displayName(): +def test_createCourseDisplayName(): '''tests for the successful implementation of combining course name and number to proper format''' - assert 'Databases' == displayName("Databases", '') - assert 'Databases' == displayName("Databases", "") - assert 'FRN 103 - Frenchy Help' == displayName("Frenchy Help", 'FRN 103') - assert 'FRN 103' == displayName("", 'FRN 103') - assert '' == displayName ("", '') + assert 'Databases' == createCourseDisplayName("Databases", '') + assert 'Databases' == createCourseDisplayName("Databases", "") + assert 'FRN 103 - Frenchy Help' == createCourseDisplayName("Frenchy Help", 'FRN 103') + assert 'FRN 103' == createCourseDisplayName("", 'FRN 103') + assert '' == createCourseDisplayName ("", '') From c83af4f377246d56725b5cc7aaf91bede2e73254 Mon Sep 17 00:00:00 2001 From: jahatehs Date: Thu, 27 Jun 2024 10:07:17 -0400 Subject: [PATCH 078/473] All done except the path extraction from config. Still in progress. --- app/controllers/admin/routes.py | 17 +++++++++++++++++ app/templates/admin/reports.html | 26 ++++++++++++++++++++++++++ app/templates/sidebar.html | 5 +++++ 3 files changed, 48 insertions(+) create mode 100644 app/templates/admin/reports.html diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index bf7de956f..ffc9d3549 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -38,6 +38,23 @@ from app.logic.serviceLearningCourses import parseUploadedFile, saveCourseParticipantsToDatabase, unapprovedCourses, approvedCourses, getImportedCourses, getInstructorCourses, editImportedCourses from app.controllers.admin import admin_bp +# ################################################################# +from flask import Blueprint, send_file, render_template, request +from app.controllers.admin import admin_bp +from app.logic.spreadsheet import createSpreadsheet + + +@admin_bp.route('/admin/reports') +def reports(): + return render_template("/admin/reports.html") + +@admin_bp.route('/download') +def download_file(): + academic_year = request.args.get('academic_year', '2023-2024') # Default academic year if not provided + filepath = createSpreadsheet(academic_year) + return send_file(filepath, as_attachment=True) + +# ################################################################## @admin_bp.route('/switch_user', methods=['POST']) def switchUser(): diff --git a/app/templates/admin/reports.html b/app/templates/admin/reports.html new file mode 100644 index 000000000..f01067773 --- /dev/null +++ b/app/templates/admin/reports.html @@ -0,0 +1,26 @@ +{% set title = "Download Reports" %} +{% extends "base.html" %} + + +{% block styles %} + {{ super() }} + +{% endblock %} + +{% block app_content %} +
+

Download the Spreadsheet

+ +
+ + +
+ + +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/sidebar.html b/app/templates/sidebar.html index 8c99d733f..a1f2f7a37 100644 --- a/app/templates/sidebar.html +++ b/app/templates/sidebar.html @@ -75,6 +75,11 @@ Minor Management + + + Reports + + {% endif %} From f242cfb6313c638136b3bfea07419db49713e252 Mon Sep 17 00:00:00 2001 From: dea Date: Thu, 27 Jun 2024 10:12:00 -0400 Subject: [PATCH 079/473] Solved the issue, but used list and dictionary to extract information --- app/logic/serviceLearningCourses.py | 49 +++++++++++++---------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 010a3334a..9d2eb92b0 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -63,39 +63,32 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li data = Course.select().where(Course.courseAbbreviation == course).order_by(Course.term.desc()).limit(1) get_existing_info = list(data.dicts()) - if not get_existing_info: -<<<<<<< HEAD print("########################################################") - courseObj: Course = Course.get_or_create( -======= - print("############################################################################################") - courseObj: Course = Course.create( ->>>>>>> 40fcba960e38fa07d49f286d05fd9f740784423d - defaults = {"CourseName" : "", - "sectionDesignation" : "", - "courseCredit" : "1", - "term" : termObj, - "status" : 4, - "createdBy" : g.current_user, - "serviceLearningDesignatedSections" : "", - "previouslyApprovedDescription" : "" })[0] + print(course) + courseObj: Course = Course.create(courseName = "", + sectionDesignation = "", + courseAbbreviation = course, + courseCredit = "1", + term = termObj, + status = 4, + createdBy = g.current_user, + serviceLearningDesignatedSections = "", + previouslyApprovedDescription = "" ) else : existing_info_dict = get_existing_info[0] - print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - print(existing_info_dict['courseName']) - courseObj: Course = Course.get_or_create( - # courseAbbreviation = course, - # term = termObj, - defaults = {"CourseName" : existing_info_dict['courseName'], - "sectionDesignation" : "", - "courseCredit" : "1", - "term" : termObj, - "status" : 4, - "createdBy" : g.current_user, - "serviceLearningDesignatedSections" : "", - "previouslyApprovedDescription" : "" })[0] + print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") + print(existing_info_dict) + courseObj: Course = Course.create(courseName = existing_info_dict['courseName'], + courseAbbreviation = existing_info_dict['courseAbbreviation'], + sectionDesignation = existing_info_dict['sectionDesignation'], + courseCredit = 1, + term = termObj, + status = 4, + createdBy = g.current_user, + serviceLearningDesignatedSections = existing_info_dict['serviceLearningDesignatedSections'], + previouslyApprovedDescription = existing_info_dict['previouslyApprovedDescription']) for userDict in courseInfo['students']: if userDict['errorMsg']: From ef874e4652d903dd920ff81ef5e3ccc5ac3ea63c Mon Sep 17 00:00:00 2001 From: Eun Sung Wang <156254694+esw0624@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:23:56 -0400 Subject: [PATCH 080/473] Standby --- app/templates/admin/createEvent.html | 2 +- app/templates/displayFilesMacro.html | 15 ++++++++++++++- app/templates/eventView.html | 21 +++++++++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 22e88b3c6..ba95c5eb4 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -267,7 +267,7 @@

{{page_title}}

{% endif %} -
+
diff --git a/app/templates/displayFilesMacro.html b/app/templates/displayFilesMacro.html index e8af00dd0..c083359d2 100644 --- a/app/templates/displayFilesMacro.html +++ b/app/templates/displayFilesMacro.html @@ -23,7 +23,20 @@ {% set idx = key.index("/") %} {% set fileName = key[idx+1:] %} {% set shortName = fileName[:8] + "..." + fileName[-10:] if fileName|length > 25 else fileName %} - {{ shortName }} + {% set iconClass = '' %} + {% if fileName.endswith('.jpg') or fileName.endswith('.jpeg') or fileName.endswith('.png') %} + {% set iconClass = 'bi-file-image' %} + {% elif fileName.endswith('.pdf') %} + {% set iconClass = 'bi-filetype-pdf' %} + {% elif fileName.endswith('.docx') %} + {% set iconClass = 'bi-filetype-docx' %} + {% elif fileName.endswith('.xlsx') %} + {% set iconClass = 'bi-filetype-xlsx' %} + {% else %} + {% set iconClass = 'bi-file-earmark-arrow-up' %} + {% endif %} + + {{ shortName }}

{% if filepaths.keys()|count %} -
+
{% for key, value in filepaths.items() %} @@ -156,7 +156,24 @@

Program Trainings:

{% set fileName = key[idx+1:] %} + {% endfor %} From 8361fe2c2168608872b2123b0c2495449fd384b3 Mon Sep 17 00:00:00 2001 From: CollegeStevenLN <156225590+CollegeStevenLN@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:18:39 -0400 Subject: [PATCH 081/473] Pulled development and resolved PR comments --- app/controllers/serviceLearning/routes.py | 3 +-- app/static/js/slcNewProposal.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/serviceLearning/routes.py b/app/controllers/serviceLearning/routes.py index 724583ad9..280b1369a 100644 --- a/app/controllers/serviceLearning/routes.py +++ b/app/controllers/serviceLearning/routes.py @@ -17,7 +17,6 @@ from app.logic.downloadFile import * from app.logic.utils import getRedirectTarget, setRedirectTarget from app.controllers.serviceLearning import serviceLearning_bp -global courseIDGLOBAL @serviceLearning_bp.route('/serviceLearning/courseManagement', methods = ['GET']) @serviceLearning_bp.route('/serviceLearning/courseManagement/', methods = ['GET']) @@ -94,7 +93,7 @@ def slcCancelProposal(): courseID = request.form.get('courseID') course = Course.get_by_id(courseID) if not course.courseName and not course.courseAbbreviation: - CourseQuestion.delete().where(CourseQuestion.course_id == courseID).execute() + CourseQuestion.delete().where(CourseQuestion.course == course) course.delete_instance() return "Proposal Canceled" diff --git a/app/static/js/slcNewProposal.js b/app/static/js/slcNewProposal.js index 1b3f711d1..130913a99 100644 --- a/app/static/js/slcNewProposal.js +++ b/app/static/js/slcNewProposal.js @@ -83,7 +83,7 @@ $(document).ready(function(e) { method: 'POST', data: {courseID : document.getElementById('courseID').value}, success: function(response) { - msgToast("Proposal Canceled", "Successfully canceled the proposal edit/creation.") + msgFlash("Proposal Canceled", "Successfully canceled the proposal edit/creation.") }, error: function(error) { msgFlash('Error: ', error) From f3cfa9ab88f2c739a929831ba36da865b7b37b20 Mon Sep 17 00:00:00 2001 From: zawn Date: Thu, 27 Jun 2024 17:54:29 +0000 Subject: [PATCH 082/473] the page is now functional --- app/static/js/eventKiosk.js | 94 ++++++++++++++++++++++------ app/templates/events/eventKiosk.html | 41 ++++++------ 2 files changed, 97 insertions(+), 38 deletions(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index 430702c0d..fad7715e0 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -1,20 +1,67 @@ +var elem = document.getElementById("show"); +/* $(document).keydown(function(e){ - console.log(e.key) - if (e.key== "Escape"){ - $("#fullscreenCheck").prop("checked", false) - console.log("here test") - hideElements(false); - document.exitFullscreen() || document.webkitExitFullscreen() || document.msExitFullscreen() - console.log("in toggle function keydown-2") + if (e.key == "F11" && document.fullscreenElement && document.webkitFullscreenElement && document.mozFullScreenElement && document.msFullscreenElement){ + e.preventDefault(); + openFullscreen(); + } + else if (e.key == "F11" && !document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement){ + e.preventDefault(); + closeFullscreen(); + } +})*/ + +$(document).keydown(function(e) { + if (e.key === "F11") { + e.preventDefault(); + if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { + closeFullscreen(); + } else { + openFullscreen(); + } + } +}); + +function openFullscreen(){ + $("#show").css({ + 'background-color': 'white', + 'padding-top' : '10%', + 'padding-left' : '20%', + 'padding-right' : '20%' + }) + + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.webkitRequestFullscreen) { /* Safari */ + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { /* IE11 */ + elem.msRequestFullscreen(); } -}) + $("#fullscreenCheck").attr("onclick", "closeFullscreen()").text("Close Full Screen"); +} + +function closeFullscreen(){ + $("#show").css({ + 'background-color': 'white', + 'padding-top' : '0%', + 'padding-left' : '0%', + 'padding-right' : '0%' + }) + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (elem.webkitRequestFullscreen) { /* Safari */ + document.webkitExitFullscreen(); + } else if (elem.msRequestFullscreen) { /* IE11 */ + document.msExitFullscreen(); + } + $("#fullscreenCheck").attr("onclick", "openFullscreen()").text("Open Full Screen"); +} $(document).ready(function(e) { $("#submitScannerData").focus(); $("#submitScannerData").keydown(function(e) { - console.log("in submit keydopnw") if (e.key === "Enter") { submitData(); } @@ -94,7 +141,7 @@ function submitData(){ }) } -function hideElements(hide) { +/*function hideElements(hide) { if (hide == true) { $("col-md-auto d-print-none d-lg-none").css("width", "0"); $("footer").hide(); @@ -124,10 +171,7 @@ function hideElements(hide) { // Source: https://stackoverflow.com/questions/1125084/how-to-make-the-window-full-screen-with-javascript-stretching-all-over-the-screen function toggleFullscreen() { if($("#fullscreenCheck").prop("checked") == true){ - exited = true - console.log(exited) hideElements(true); - var el = document.documentElement , rfs = // for newer Webkit and Firefox el.requestFullscreen @@ -138,24 +182,34 @@ function toggleFullscreen() { if(typeof rfs!="undefined" && rfs){ rfs.call(el); - }else if(typeof window.ActiveXObject!="undefined"){ + exited = false + + }else if(typeof window.ActiveXObject!="undefined"){ // for Internet Explorer + exited = false + var wscript = new ActiveXObject("WScript.Shell"); if (wscript!=null) { + exited = false + wscript.SendKeys("{F11}"); } } }else if ($("#fullscreenCheck").prop("checked") == false){ - console.log("here test") hideElements(false); document.exitFullscreen() || document.webkitExitFullscreen() || document.msExitFullscreen() - console.log("in toggle function keydown-2") } $('#submitScannerData').focus(); + }; -/*if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { +/* if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { + console.log("Fullscreen mode was entered"); + hideElements(true); + console.log("here wewe") +} else { + console.log("Fullscreen mode was exited"); +}if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { console.log("Fullscreen mode was exited"); }*/ -if (document.fullscreenElement && document.webkitFullscreenElement && document.mozFullScreenElement && document.msFullscreenElement) { - console.log("Fullscreen mode was entered"); -} + + diff --git a/app/templates/events/eventKiosk.html b/app/templates/events/eventKiosk.html index 38ea275ca..0ef89cf20 100644 --- a/app/templates/events/eventKiosk.html +++ b/app/templates/events/eventKiosk.html @@ -11,25 +11,30 @@ {% endblock %} {% block app_content %} - -
-

{{ event.name }}

-

{{ bNumberToUser }}

-
-
-
- - - +
+ +
+

{{ event.name }}

+

{{ bNumberToUser }}

- -
-
- Back -
-
- - +
+
+ + + +
+ +
+
+ Back +
+
+ + +
{% endblock %} From 73ae4ecaa8cb3975334a66bb0c655c6a558fdcd2 Mon Sep 17 00:00:00 2001 From: Eun Sung Wang <156254694+esw0624@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:07:48 -0400 Subject: [PATCH 083/473] Final Update for this issue --- app/static/css/base.css | 4 ++++ app/static/css/eventList.css | 6 +++++- app/templates/admin/createEvent.html | 2 +- app/templates/displayFilesMacro.html | 14 ++++++++------ app/templates/eventView.html | 6 ++---- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/app/static/css/base.css b/app/static/css/base.css index 74fcddcc6..d6d49a299 100644 --- a/app/static/css/base.css +++ b/app/static/css/base.css @@ -102,4 +102,8 @@ select.empty { .rsvp-btn{ padding-top: 4em; +} + +.icon { + margin-right: 100px; /* Adjust the value as needed */ } \ No newline at end of file diff --git a/app/static/css/eventList.css b/app/static/css/eventList.css index 801935a19..8f78db8b9 100644 --- a/app/static/css/eventList.css +++ b/app/static/css/eventList.css @@ -1,3 +1,7 @@ .accordion-button::after { margin-left: 1.5rem; -} \ No newline at end of file +} + +.icon { + margin-right: 20px; /* Adjust the value as needed */ + } \ No newline at end of file diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index ba95c5eb4..22e88b3c6 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -267,7 +267,7 @@

{{page_title}}

{% endif %} -
+
diff --git a/app/templates/displayFilesMacro.html b/app/templates/displayFilesMacro.html index a008a6c7f..242b61f41 100644 --- a/app/templates/displayFilesMacro.html +++ b/app/templates/displayFilesMacro.html @@ -1,15 +1,16 @@ -{% macro displayFiles(filePaths, titleName, deleteLink, databaseId) %} +{% macro displayFiles(filePaths, titleName, deleteLink, databaseId) %}
- {{fileName}} + {% set shortName = fileName[:8] + "..." + fileName[-10:] if fileName|length > 25 else fileName %} + {% set iconClass = '' %} + {% if fileName.endswith('.jpg') or fileName.endswith('.jpeg') or fileName.endswith('.png') %} + {% set iconClass = 'bi-file-image' %} + {% elif fileName.endswith('.pdf') %} + {% set iconClass = 'bi-filetype-pdf' %} + {% elif fileName.endswith('.docx') %} + {% set iconClass = 'bi-filetype-docx' %} + {% elif fileName.endswith('.xlsx') %} + {% set iconClass = 'bi-filetype-xlsx' %} + {% else %} + {% set iconClass = 'bi-file-earmark-arrow-up' %} + {% endif %} + + + + {{ shortName }}
+ {% for key, value in filePaths.items() %} -
Display {{ titleName }}
- + + {% if value[0].endswith('.png') or value[0].endswith('.PNG') or value[0].endswith('.jpg') or value[0].endswith('.JPG') or value[0].endswith('.svg') or value[0].endswith('.SVG') or value[0].endswith('.jpeg') or value[0].endswith('.JPEG') or value[0].endswith('.gif') or value[0].endswith('.GIF') %} + + {% endif %} {% set idx = key.index("/") %} @@ -27,7 +28,7 @@ {% else %} {% set iconClass = 'bi-file-earmark-arrow-up' %} {% endif %} - + {{ shortName }} @@ -45,3 +46,4 @@
{% endmacro %} + diff --git a/app/templates/eventView.html b/app/templates/eventView.html index 952024020..7356208f2 100644 --- a/app/templates/eventView.html +++ b/app/templates/eventView.html @@ -148,7 +148,7 @@

Program Trainings:

{% if filepaths.keys()|count %} -
+
Event Attachments {% for key, value in filepaths.items() %} @@ -169,9 +169,7 @@

Program Trainings:

{% else %} {% set iconClass = 'bi-file-earmark-arrow-up' %} {% endif %} - + From 72b2bcbb6de5695c63b9de166c1cadee13ae9896 Mon Sep 17 00:00:00 2001 From: zawn Date: Thu, 27 Jun 2024 18:19:57 +0000 Subject: [PATCH 084/473] fixed everything gertrude recommend the code for focus. --- app/static/js/eventKiosk.js | 95 +++------------------------- app/templates/events/eventKiosk.html | 4 -- 2 files changed, 8 insertions(+), 91 deletions(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index fad7715e0..545fd7a1f 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -1,16 +1,4 @@ var elem = document.getElementById("show"); -/* -$(document).keydown(function(e){ - if (e.key == "F11" && document.fullscreenElement && document.webkitFullscreenElement && document.mozFullScreenElement && document.msFullscreenElement){ - e.preventDefault(); - openFullscreen(); - } - else if (e.key == "F11" && !document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement){ - e.preventDefault(); - closeFullscreen(); - } -})*/ - $(document).keydown(function(e) { if (e.key === "F11") { e.preventDefault(); @@ -22,6 +10,7 @@ $(document).keydown(function(e) { } }); + function openFullscreen(){ $("#show").css({ 'background-color': 'white', @@ -37,9 +26,14 @@ function openFullscreen(){ } else if (elem.msRequestFullscreen) { /* IE11 */ elem.msRequestFullscreen(); } + ensureFocus(); $("#fullscreenCheck").attr("onclick", "closeFullscreen()").text("Close Full Screen"); } - +function ensureFocus() { + if (!$("#submitScannerData").is(":focus")) { + $("#submitScannerData").focus(); + } +} function closeFullscreen(){ $("#show").css({ 'background-color': 'white', @@ -54,13 +48,13 @@ function closeFullscreen(){ } else if (elem.msRequestFullscreen) { /* IE11 */ document.msExitFullscreen(); } + ensureFocus(); $("#fullscreenCheck").attr("onclick", "openFullscreen()").text("Open Full Screen"); } $(document).ready(function(e) { $("#submitScannerData").focus(); - $("#submitScannerData").keydown(function(e) { if (e.key === "Enter") { submitData(); @@ -140,76 +134,3 @@ function submitData(){ } }) } - -/*function hideElements(hide) { - if (hide == true) { - $("col-md-auto d-print-none d-lg-none").css("width", "0"); - $("footer").hide(); - $("kiosk-hide").animate({ opacity: 0 }, 1); - $("kiosk-hide").css("width", "0"); - $("kiosk-hide").prop("disabled", true); - $("position-fixed float-start").hide(); - $("position-fixed float-start").css("width", "0"); - $("#sideBarContainer").attr("class", "col-md-0 d-print-none d-none d-lg-block") - $("#sideBar").attr("class", "position-fixed float-start d-none") - $("#sideBarSandwichUI").attr("class","btn btn-dark rounded-0 rounded-end kiosk-hide d-none") - } else - { - console.log("in hide element before keydown") - $("footer").show(); - $("kiosk-hide").css("width", "inherit"); - $("kiosk-hide").animate({ opacity: 1 }, 1); - $("kiosk-hide").prop("disabled", false); - $("a").show(); - $("#sideBarContainer").attr("class", "col-md-auto d-print-none d-none d-lg-block") - $("#sideBar").attr("class", "position-fixed float-start") - $("#sideBarSandwichUI").attr("class","btn btn-dark rounded-0 rounded-end kiosk-hide") - console.log("in hide element after keydown") - } -} - -// Source: https://stackoverflow.com/questions/1125084/how-to-make-the-window-full-screen-with-javascript-stretching-all-over-the-screen -function toggleFullscreen() { - if($("#fullscreenCheck").prop("checked") == true){ - hideElements(true); - var el = document.documentElement - , rfs = // for newer Webkit and Firefox - el.requestFullscreen - || el.webkitRequestFullScreen - || el.mozRequestFullScreen - || el.msRequestFullscreen - ; - - if(typeof rfs!="undefined" && rfs){ - rfs.call(el); - exited = false - - }else if(typeof window.ActiveXObject!="undefined"){ - // for Internet Explorer - exited = false - - var wscript = new ActiveXObject("WScript.Shell"); - if (wscript!=null) { - exited = false - - wscript.SendKeys("{F11}"); - } - } - }else if ($("#fullscreenCheck").prop("checked") == false){ - hideElements(false); - document.exitFullscreen() || document.webkitExitFullscreen() || document.msExitFullscreen() - } - $('#submitScannerData').focus(); - -}; -/* if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { - console.log("Fullscreen mode was entered"); - hideElements(true); - console.log("here wewe") -} else { - console.log("Fullscreen mode was exited"); -}if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { - console.log("Fullscreen mode was exited"); -}*/ - - diff --git a/app/templates/events/eventKiosk.html b/app/templates/events/eventKiosk.html index 0ef89cf20..e2ac888a1 100644 --- a/app/templates/events/eventKiosk.html +++ b/app/templates/events/eventKiosk.html @@ -30,10 +30,6 @@

{{ bNumberToUser }}

-
From fd17376e4c8acb1b4bec8d6a96417cd74ac9ee43 Mon Sep 17 00:00:00 2001 From: Josh Wakin Date: Thu, 27 Jun 2024 14:27:01 -0400 Subject: [PATCH 085/473] implemented get_or_none method to servicelearningcourse.py --- app/logic/serviceLearningCourses.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 9d2eb92b0..1c5ae941b 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -60,12 +60,12 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li if 'errorMsg' in courseInfo and courseInfo['errorMsg']: print(f"Unable to save course {course}. {courseInfo['errorMsg']}") continue - data = Course.select().where(Course.courseAbbreviation == course).order_by(Course.term.desc()).limit(1) - get_existing_info = list(data.dicts()) - if not get_existing_info: - print("########################################################") - print(course) + data = Course.get_or_none(Course.courseAbbreviation == course),(Course.term.desc()) + print("#################################################################") + print(data) + if data == None : + courseObj: Course = Course.create(courseName = "", sectionDesignation = "", courseAbbreviation = course, @@ -77,18 +77,18 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li previouslyApprovedDescription = "" ) else : - existing_info_dict = get_existing_info[0] + print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") - print(existing_info_dict) - courseObj: Course = Course.create(courseName = existing_info_dict['courseName'], - courseAbbreviation = existing_info_dict['courseAbbreviation'], - sectionDesignation = existing_info_dict['sectionDesignation'], + + courseObj: Course = Course.create(courseName = data.courseName, + courseAbbreviation = data.courseAbbreviation, + sectionDesignation = data.sectionDesignation, courseCredit = 1, term = termObj, status = 4, createdBy = g.current_user, - serviceLearningDesignatedSections = existing_info_dict['serviceLearningDesignatedSections'], - previouslyApprovedDescription = existing_info_dict['previouslyApprovedDescription']) + serviceLearningDesignatedSections = data.serviceLearningDesignatedSections, + previouslyApprovedDescription =data.previouslyApprovedDescription) for userDict in courseInfo['students']: if userDict['errorMsg']: From afa38ea8d7faf055599c29bd6100f44990d85dcf Mon Sep 17 00:00:00 2001 From: CollegeStevenLN <156225590+CollegeStevenLN@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:51:23 -0400 Subject: [PATCH 086/473] Fixed ajax issue with page reload --- app/controllers/serviceLearning/routes.py | 2 +- app/static/js/slcNewProposal.js | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/app/controllers/serviceLearning/routes.py b/app/controllers/serviceLearning/routes.py index 280b1369a..a9a8c2244 100644 --- a/app/controllers/serviceLearning/routes.py +++ b/app/controllers/serviceLearning/routes.py @@ -93,7 +93,7 @@ def slcCancelProposal(): courseID = request.form.get('courseID') course = Course.get_by_id(courseID) if not course.courseName and not course.courseAbbreviation: - CourseQuestion.delete().where(CourseQuestion.course == course) + CourseQuestion.delete().where(CourseQuestion.course_id == courseID).execute() course.delete_instance() return "Proposal Canceled" diff --git a/app/static/js/slcNewProposal.js b/app/static/js/slcNewProposal.js index 130913a99..8bab2027f 100644 --- a/app/static/js/slcNewProposal.js +++ b/app/static/js/slcNewProposal.js @@ -78,19 +78,15 @@ $(document).ready(function(e) { }); $("#cancelButton").on("click", function() { - $.ajax({ - url: '/serviceLearning/canceledProposal', - method: 'POST', - data: {courseID : document.getElementById('courseID').value}, - success: function(response) { - msgFlash("Proposal Canceled", "Successfully canceled the proposal edit/creation.") - }, - error: function(error) { - msgFlash('Error: ', error) - - } - }); - window.location.replace($(this).val()); + var cancelButtonContext = this + $.ajax({ + url: '/serviceLearning/canceledProposal', + method: 'POST', + data: {courseID : document.getElementById('courseID').value}, + success: function(response) { + window.location.replace($(cancelButtonContext).val()); + } + }) }); $("#saveContinue").on("click", function() { From eb5d02a6e4479354fad9e6b9c224f505ca495b5e Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Thu, 27 Jun 2024 20:04:32 +0000 Subject: [PATCH 087/473] Save button mostly fixed --- app/static/js/createEvents.js | 126 +++++++++++++++++----------------- 1 file changed, 62 insertions(+), 64 deletions(-) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index b44f2c422..6cb786d1e 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -66,84 +66,82 @@ function format24to12HourTime(timeStr){ var save_button = document.getElementById('submitParticipant'); var modal = document.getElementById('modalCustom'); - - save_button.addEventListener('click', function() { + +// Assuming save_button is properly defined elsewhere in your code +save_button.addEventListener('click', function() { // Call the function storingCustomEventAttributes() when the button is clicked - $("#checkIsCustom").prop('checked', true); storingCustomEventAttributes(); $("#checkIsCustom").prop('checked', true); // Remove the modal and overlay from the DOM $('#modalCustom').modal('hide'); +}); - }); - - +let entries = []; - - -let entries = [] function storingCustomEventAttributes() { - - $(".extraSlots").children().each(function(index, element) { - let rowData = $.map($(element).find("input"), (el) => $(el).val()); - console.log("Data in row " + (index + 1) + ": " + rowData); - console.log(rowData) - - entries.push({ - eventDate: rowData[0], - startTime: rowData[1], - endTime: rowData[2], - isCustom: 'true' - }); - // Clear previous content - $('#displayEntries').empty(); - - // Iterate through entries array - entries.forEach(function(entry, index) { - // Create a string with entry details - let entryString = ` -

Event Date: ${entry.eventDate}

-

Start Time: ${entry.startTime}

-

End Time: ${entry.endTime}

-

Is Custom: ${entry.isCustom}

-
- `; - - // Append entry details to displayEntries div - $('#displayEntries').append(entryString); + $(".extraSlots").children().each(function(index, element) { + let rowData = $.map($(element).find("input"), (el) => $(el).val()); + console.log("Data in row " + (index + 1) + ": " + rowData); + + entries.push({ + eventDate: rowData[0], + startTime: rowData[1], + endTime: rowData[2] + }); }); + console.log(entries); + console.log(typeof entires) + console.log(entries) - + var customTable = $("#customEventsTable"); + entries.forEach(function(entry){ + customTable.append("
"); }); - console.log(entries) - $.ajax({ - type:"POST", - url: "/makeCustomEvents", - data: entries, //get the startDate, endDate and name as a dictionary - success: function(jsonData){ - var customEvents = JSON.parse(jsonData) - var customTable = $("#customEventsTable") - $("#customEventsTable tbody tr").remove(); - - - - for (var event of customEvents){ - var eventdate = new Date(event.date).toLocaleDateString() - var startTime = new TimeRanges(event.startTime).String() - var endTime = new TimeRanges(event.endTime).String() - - customTable.append(""); - } - }, - error: function(error){ - console.log(error) - } - }); - -} +} + + + +// $.ajax({ +// type: "POST", +// url: "/makeCustomEvents", +// data: { events: entries }, // Send data as an object +// success: function(jsonData) { +// console.log("success AJAX call"); +// console.log(jsonData); + +// var customEvents = JSON.parse(jsonData); +// var customTable = $("#customEventsTable"); +// customTable.find("tbody tr").remove(); // Clear existing rows + +// console.log("Data Type of", typeof customEvents); +// console.log(customEvents); + +// // Check if customEvents is an object +// if (typeof customEvents === 'object' && !Array.isArray(customEvents)) { +// // Iterate over the properties of the object using for...in +// for (var key in customEvents) { +// console.log(key) +// if (customEvents.hasOwnProperty(key)) { +// var event = customEvents[key]; +// console.log(event) +// var eventDate = new Date(event.date).toLocaleDateString(); +// var startTime = event.startTime; +// var endTime = event.endTime; + +// customTable.append(""); +// } +// } +// } else { +// console.error("customEvents is not an object:", customEvents); +// } +// }, +// error: function(error) { +// console.log(error); +// } +// }); // var customDatesAndTimes = { // name: $("#inputEventName").val(), // isCustom: true, From 931c59faea660eac4510a85b89183c64e39dce46 Mon Sep 17 00:00:00 2001 From: Eun Sung Wang <156254694+esw0624@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:13:14 -0400 Subject: [PATCH 088/473] Done with changes! --- app/static/css/base.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/static/css/base.css b/app/static/css/base.css index d6d49a299..74fcddcc6 100644 --- a/app/static/css/base.css +++ b/app/static/css/base.css @@ -102,8 +102,4 @@ select.empty { .rsvp-btn{ padding-top: 4em; -} - -.icon { - margin-right: 100px; /* Adjust the value as needed */ } \ No newline at end of file From 0825911907d1427c8e389833fd68d17f5b3afab3 Mon Sep 17 00:00:00 2001 From: vungc Date: Thu, 27 Jun 2024 16:24:56 -0400 Subject: [PATCH 089/473] datepicker shows up when calendar icon is clicked for clones, but only for the most recent clone and not yet working properly --- app/static/js/createEvents.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index 6cb786d1e..7edbd05fb 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -283,10 +283,19 @@ $(document).ready(function() { counterAdd += 1 let clonedCustom = $("#customEvent").clone();// this line clones the customEvent id div in the custom event modal on createEvent.html line 403 clonedCustom.attr("id", "customEvent" + counterAdd) + clonedCustom.find("[id^='customDate']").attr("id", "customDate-" + counterAdd); + clonedCustom.find("[data-page-location]").attr("id", "customDatePicker-" + counterAdd); + clonedCustom.find("[data-page-location]").attr("data-page-location", counterAdd); + clonedCustom.find("[id^='calendarIconStart']").attr("id", "calendarIconStart-" + counterAdd); + clonedCustom.find("[id^='customDatePicker']").attr("id", "customDatePicker-" + counterAdd); $(".extraSlots").append(clonedCustom) $("#customEvent" + counterAdd).children("div#delete_customevent").attr("id", "delete_customevent" + counterAdd) //this line finds the id delete_customevent within the parent customevent and change the id attribute $("#delete_customevent" + counterAdd).removeClass('d-none'); + $('#calendarIconStart-' + counterAdd).click(function() { + console.log('ok') + $('#customDatePicker-'+ counterAdd).datepicker().datepicker('show'); + }); clonedCustom.find(".delete_customevent").attr("id", "delete_customevent" + counterAdd).removeClass('d-none'); From 0e6343be0aa111cd85e0c4e6ad11cdc8916d3aeb Mon Sep 17 00:00:00 2001 From: Josh Wakin Date: Thu, 27 Jun 2024 16:28:53 -0400 Subject: [PATCH 090/473] saveCourseParticipantsToDatabase now passes info from existing courses, IF the course already the course already --- app/logic/serviceLearningCourses.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 1c5ae941b..a8b11c51f 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -61,10 +61,13 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li print(f"Unable to save course {course}. {courseInfo['errorMsg']}") continue - data = Course.get_or_none(Course.courseAbbreviation == course),(Course.term.desc()) - print("#################################################################") - print(data) - if data == None : + data = list((Course.select().where(Course.courseAbbreviation == course ).order_by(Course.term.desc()).limit(1))) + + print("#################################################################LOOKIE") + + + + if not data : courseObj: Course = Course.create(courseName = "", sectionDesignation = "", @@ -79,16 +82,18 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li else : print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") + + existing_data =data[0] - courseObj: Course = Course.create(courseName = data.courseName, - courseAbbreviation = data.courseAbbreviation, - sectionDesignation = data.sectionDesignation, + courseObj: Course = Course.create(courseName = existing_data.courseName, + courseAbbreviation = existing_data.courseAbbreviation, + sectionDesignation = existing_data.sectionDesignation, courseCredit = 1, term = termObj, status = 4, createdBy = g.current_user, - serviceLearningDesignatedSections = data.serviceLearningDesignatedSections, - previouslyApprovedDescription =data.previouslyApprovedDescription) + serviceLearningDesignatedSections = existing_data.serviceLearningDesignatedSections, + previouslyApprovedDescription = existing_data.previouslyApprovedDescription) for userDict in courseInfo['students']: if userDict['errorMsg']: From 981cfcd04f85ab982b651ccbc8b5e2996346dc64 Mon Sep 17 00:00:00 2001 From: jahatehs Date: Thu, 27 Jun 2024 16:56:59 -0400 Subject: [PATCH 091/473] We created a reports UI under Admin tab. UI includes a download button and an input bar for the year to download the report. --- app/controllers/admin/routes.py | 10 ++++++---- app/templates/admin/reports.html | 11 ++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index ffc9d3549..20fd42ef1 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -38,23 +38,25 @@ from app.logic.serviceLearningCourses import parseUploadedFile, saveCourseParticipantsToDatabase, unapprovedCourses, approvedCourses, getImportedCourses, getInstructorCourses, editImportedCourses from app.controllers.admin import admin_bp -# ################################################################# -from flask import Blueprint, send_file, render_template, request +from flask import send_file, render_template, request from app.controllers.admin import admin_bp from app.logic.spreadsheet import createSpreadsheet @admin_bp.route('/admin/reports') def reports(): - return render_template("/admin/reports.html") + academic_years = Term.select(Term.academicYear).distinct().order_by(Term.academicYear.desc()) + academic_years = list(map(lambda t: t.academicYear, academic_years)) + return render_template("/admin/reports.html", academic_years=academic_years) @admin_bp.route('/download') def download_file(): academic_year = request.args.get('academic_year', '2023-2024') # Default academic year if not provided filepath = createSpreadsheet(academic_year) + filepath = os.path.abspath(filepath) + return send_file(filepath, as_attachment=True) -# ################################################################## @admin_bp.route('/switch_user', methods=['POST']) def switchUser(): diff --git a/app/templates/admin/reports.html b/app/templates/admin/reports.html index f01067773..a7f7b99da 100644 --- a/app/templates/admin/reports.html +++ b/app/templates/admin/reports.html @@ -14,11 +14,16 @@ {% block app_content %}
-

Download the Spreadsheet

+

Download Reports

- - + +
From 17665326315e6712004b7ae9dfe90c811ef7aa21 Mon Sep 17 00:00:00 2001 From: zawn Date: Thu, 27 Jun 2024 21:04:59 +0000 Subject: [PATCH 092/473] I have done research on event listner --- app/static/js/eventKiosk.js | 82 ++++++++++++++++++++++++++++ app/templates/events/eventKiosk.html | 2 +- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index 545fd7a1f..faf185945 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -1,4 +1,12 @@ var elem = document.getElementById("show"); + +$(document).on("fullscreenchange", function(){ + if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { + closeFullscreen(); + } else { + openFullscreen(); + } +}) $(document).keydown(function(e) { if (e.key === "F11") { e.preventDefault(); @@ -134,3 +142,77 @@ function submitData(){ } }) } + +/*function hideElements(hide) { + if (hide == true) { + $("col-md-auto d-print-none d-lg-none").css("width", "0"); + $("footer").hide(); + $("kiosk-hide").animate({ opacity: 0 }, 1); + $("kiosk-hide").css("width", "0"); + $("kiosk-hide").prop("disabled", true); + $("position-fixed float-start").hide(); + $("position-fixed float-start").css("width", "0"); + $("#sideBarContainer").attr("class", "col-md-0 d-print-none d-none d-lg-block") + $("#sideBar").attr("class", "position-fixed float-start d-none") + $("#sideBarSandwichUI").attr("class","btn btn-dark rounded-0 rounded-end kiosk-hide d-none") + } else + { + console.log("in hide element before keydown") + $("footer").show(); + $("kiosk-hide").css("width", "inherit"); + $("kiosk-hide").animate({ opacity: 1 }, 1); + $("kiosk-hide").prop("disabled", false); + $("a").show(); + $("#sideBarContainer").attr("class", "col-md-auto d-print-none d-none d-lg-block") + $("#sideBar").attr("class", "position-fixed float-start") + $("#sideBarSandwichUI").attr("class","btn btn-dark rounded-0 rounded-end kiosk-hide") + console.log("in hide element after keydown") + } +} + +// Source: https://stackoverflow.com/questions/1125084/how-to-make-the-window-full-screen-with-javascript-stretching-all-over-the-screen +function toggleFullscreen() { + if($("#fullscreenCheck").prop("checked") == true){ + hideElements(true); + var el = document.documentElement + , rfs = // for newer Webkit and Firefox + el.requestFullscreen + || el.webkitRequestFullScreen + || el.mozRequestFullScreen + || el.msRequestFullscreen + ; + + if(typeof rfs!="undefined" && rfs){ + rfs.call(el); + exited = false + + }else if(typeof window.ActiveXObject!="undefined"){ + // for Internet Explorer + exited = false + + var wscript = new ActiveXObject("WScript.Shell"); + if (wscript!=null) { + exited = false + + wscript.SendKeys("{F11}"); + } + } + }else if ($("#fullscreenCheck").prop("checked") == false){ + hideElements(false); + document.exitFullscreen() || document.webkitExitFullscreen() || document.msExitFullscreen() + } + $('#submitScannerData').focus(); + +}; +/* if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { + console.log("Fullscreen mode was entered"); + hideElements(true); + console.log("here wewe") +} else { + console.log("Fullscreen mode was exited"); +}if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { + console.log("Fullscreen mode was exited"); +}*/ + + + diff --git a/app/templates/events/eventKiosk.html b/app/templates/events/eventKiosk.html index e2ac888a1..2b1df681e 100644 --- a/app/templates/events/eventKiosk.html +++ b/app/templates/events/eventKiosk.html @@ -29,7 +29,7 @@

{{ bNumberToUser }}

Back
- +
From d07818b2fd413ab95e5ac75293bc0e2f982fdd6f Mon Sep 17 00:00:00 2001 From: zawn Date: Fri, 28 Jun 2024 13:44:54 +0000 Subject: [PATCH 093/473] was able to listen to the first escape --- app/static/js/eventKiosk.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index faf185945..5db351638 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -1,13 +1,14 @@ var elem = document.getElementById("show"); -$(document).on("fullscreenchange", function(){ - if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { +$(document).on("fullscreenchange", function(){ // this listen to the full screen event //https://developer.mozilla.org/en-US/docs/Web/API/Element/fullscreenchange_event + /*if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { closeFullscreen(); } else { openFullscreen(); - } + }*/ + console.log("yippie") }) -$(document).keydown(function(e) { +$(document).keydown(function(e) { // this is for F11 keydown if (e.key === "F11") { e.preventDefault(); if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { @@ -19,7 +20,7 @@ $(document).keydown(function(e) { }); -function openFullscreen(){ +function openFullscreen(){ // open full screen function $("#show").css({ 'background-color': 'white', 'padding-top' : '10%', @@ -34,7 +35,7 @@ function openFullscreen(){ } else if (elem.msRequestFullscreen) { /* IE11 */ elem.msRequestFullscreen(); } - ensureFocus(); + ensureFocus(); // focus function $("#fullscreenCheck").attr("onclick", "closeFullscreen()").text("Close Full Screen"); } function ensureFocus() { From d619804f43ad86701ec92b5843b6b3222e95b1ea Mon Sep 17 00:00:00 2001 From: dea Date: Fri, 28 Jun 2024 10:11:52 -0400 Subject: [PATCH 094/473] Issue fixed, but not checking for term --- app/logic/serviceLearningCourses.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index a8b11c51f..4a4ec6616 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -61,13 +61,10 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li print(f"Unable to save course {course}. {courseInfo['errorMsg']}") continue - data = list((Course.select().where(Course.courseAbbreviation == course ).order_by(Course.term.desc()).limit(1))) + check_for_Existing_Courses = list((Course.select().where(Course.courseAbbreviation == course ).order_by(Course.term.desc()).limit(1))) - print("#################################################################LOOKIE") - - - if not data : + if not check_for_Existing_Courses : courseObj: Course = Course.create(courseName = "", sectionDesignation = "", @@ -79,21 +76,23 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li serviceLearningDesignatedSections = "", previouslyApprovedDescription = "" ) + elif termObj == check_for_Existing_Courses[0].term: + + print("The course already exists") + else : - print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") + previous_data = check_for_Existing_Courses[0] - existing_data =data[0] - - courseObj: Course = Course.create(courseName = existing_data.courseName, - courseAbbreviation = existing_data.courseAbbreviation, - sectionDesignation = existing_data.sectionDesignation, + courseObj: Course = Course.create(courseName = previous_data.courseName, + courseAbbreviation = previous_data.courseAbbreviation, + sectionDesignation = previous_data.sectionDesignation, courseCredit = 1, term = termObj, status = 4, createdBy = g.current_user, - serviceLearningDesignatedSections = existing_data.serviceLearningDesignatedSections, - previouslyApprovedDescription = existing_data.previouslyApprovedDescription) + serviceLearningDesignatedSections = previous_data.serviceLearningDesignatedSections, + previouslyApprovedDescription = previous_data.previouslyApprovedDescription) for userDict in courseInfo['students']: if userDict['errorMsg']: From 2f49fb90b10866439ba06c1784009a191479d914 Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Fri, 28 Jun 2024 15:22:06 +0000 Subject: [PATCH 095/473] fixed the custom table display --- app/static/js/createEvents.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index 6cb786d1e..067ef24bb 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -76,9 +76,10 @@ save_button.addEventListener('click', function() { $('#modalCustom').modal('hide'); }); -let entries = []; + function storingCustomEventAttributes() { + let entries = []; $(".extraSlots").children().each(function(index, element) { let rowData = $.map($(element).find("input"), (el) => $(el).val()); console.log("Data in row " + (index + 1) + ": " + rowData); @@ -92,9 +93,11 @@ function storingCustomEventAttributes() { console.log(entries); console.log(typeof entires) - console.log(entries) var customTable = $("#customEventsTable"); + console.log(customTable) + customTable.find("tbody tr").remove(); // Clear existing rows + console.log(customTable) entries.forEach(function(entry){ customTable.append("
"); From f3c8b03506212fb5c0e8fc03f84673610a2ca93a Mon Sep 17 00:00:00 2001 From: Mbeweg <122580961+Mbeweg@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:17:37 +0000 Subject: [PATCH 096/473] Fixed and done --- app/static/js/eventKiosk.js | 254 +++++++++++++++++++----------------- 1 file changed, 135 insertions(+), 119 deletions(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index 5db351638..4c4ca7e46 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -1,64 +1,82 @@ var elem = document.getElementById("show"); -$(document).on("fullscreenchange", function(){ // this listen to the full screen event //https://developer.mozilla.org/en-US/docs/Web/API/Element/fullscreenchange_event - /*if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { - closeFullscreen(); - } else { - openFullscreen(); - }*/ - console.log("yippie") -}) -$(document).keydown(function(e) { // this is for F11 keydown - if (e.key === "F11") { - e.preventDefault(); +$(document).on("fullscreenchange", function() { + if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { + closeFullscreen(false); // Pass false to indicate not to toggle button text + } +}); + +$(document).keydown(function(e) { + if (e.key === "F11") { + e.preventDefault(); + toggleFullscreen(); + } +}); + +function toggleFullscreen() { if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { - closeFullscreen(); + closeFullscreen(true); // Pass true to indicate toggling button text } else { - openFullscreen(); + openFullscreen(); } - } -}); - - -function openFullscreen(){ // open full screen function - $("#show").css({ - 'background-color': 'white', - 'padding-top' : '10%', - 'padding-left' : '20%', - 'padding-right' : '20%' - }) - - if (elem.requestFullscreen) { - elem.requestFullscreen(); - } else if (elem.webkitRequestFullscreen) { /* Safari */ - elem.webkitRequestFullscreen(); - } else if (elem.msRequestFullscreen) { /* IE11 */ - elem.msRequestFullscreen(); - } - ensureFocus(); // focus function - $("#fullscreenCheck").attr("onclick", "closeFullscreen()").text("Close Full Screen"); -} +} + +function openFullscreen() { + $("#show").css({ + 'background-color': 'white', + 'position': 'absolute', + 'top': '50%', + 'left': '50%', + 'transform': 'translate(-50%, -50%)', + 'height': '100%', + 'width': '100%', + 'box-sizing': 'border-box' + }); + + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.webkitRequestFullscreen) { /* Safari */ + elem.webkitRequestFullscreen(); + } else if (elem.msRequestFullscreen) { /* IE11 */ + elem.msRequestFullscreen(); + } + ensureFocus(); + $("#fullscreenCheck").attr("onclick", "toggleFullscreen()").text("Close Full Screen"); +} + function ensureFocus() { - if (!$("#submitScannerData").is(":focus")) { - $("#submitScannerData").focus(); - } + if (!$("#submitScannerData").is(":focus")) { + $("#submitScannerData").focus(); + } } -function closeFullscreen(){ - $("#show").css({ - 'background-color': 'white', - 'padding-top' : '0%', - 'padding-left' : '0%', - 'padding-right' : '0%' - }) - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (elem.webkitRequestFullscreen) { /* Safari */ - document.webkitExitFullscreen(); - } else if (elem.msRequestFullscreen) { /* IE11 */ - document.msExitFullscreen(); - } - ensureFocus(); - $("#fullscreenCheck").attr("onclick", "openFullscreen()").text("Open Full Screen"); + +function closeFullscreen(toggleButton) { + $("#show").css({ + 'background-color': 'white', + 'position': 'static', + 'top': 'auto', + 'left': 'auto', + 'transform': 'none', + 'height': 'auto', + 'width': 'auto', + 'box-sizing': 'content-box' + }); + + if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.webkitExitFullscreen) { /* Safari */ + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { /* IE11 */ + document.msExitFullscreen(); + } + } + + ensureFocus(); + + if (toggleButton) { + $("#fullscreenCheck").attr("onclick", "toggleFullscreen()").text("Open Full Screen"); + } } $(document).ready(function(e) { @@ -70,78 +88,76 @@ $(document).ready(function(e) { } }); - // Opens the camera to scan the ID + // Opens the camera to scan the ID $('.qr-reader-button').on("click", function() { - $('#qr-reader').toggle() - let lastResult, countResults = 0; - let onScanSuccess = function(decodedText, decodedResult) { - if (decodedText && decodedText.length > 9 && decodedText !== lastResult) { - lastResult = decodedText; - - $("#submitScannerData").val(decodedText) - submitData(); - } else { - message = decodedText + " Invalid B-number" - flasherStatus = "danger" - } - } - let qrboxFunction = function(viewfinderWidth, viewfinderHeight) { - let minEdgePercentage = 0.9; // 90% - let minEdgeSize = Math.min(viewfinderWidth, viewfinderHeight); - let qrboxSize = Math.floor(minEdgeSize * minEdgePercentage); - return { - width: qrboxSize, - height: qrboxSize + $('#qr-reader').toggle(); + let lastResult, countResults = 0; + let onScanSuccess = function(decodedText, decodedResult) { + if (decodedText && decodedText.length > 9 && decodedText !== lastResult) { + lastResult = decodedText; + + $("#submitScannerData").val(decodedText); + submitData(); + } else { + message = decodedText + " Invalid B-number"; + flasherStatus = "danger"; + } }; - } - let scanner = new Html5QrcodeScanner("qr-reader", { - fps: 2, - qrbox: qrboxFunction, - preferFrontCamera: false, - facingMode: { exact: "environment" }, - useBarCodeDetectorIfSupported: true, - }, true); - scanner.render(onScanSuccess); - - - // we have to delay this so that the element exists before we try to add the event - window.setTimeout(function() { - $('#html5-qrcode-button-camera-stop').on("click", function() { - $('#qr-reader').toggle() - })}, 500); - }) + let qrboxFunction = function(viewfinderWidth, viewfinderHeight) { + let minEdgePercentage = 0.9; // 90% + let minEdgeSize = Math.min(viewfinderWidth, viewfinderHeight); + let qrboxSize = Math.floor(minEdgeSize * minEdgePercentage); + return { + width: qrboxSize, + height: qrboxSize + }; + }; + let scanner = new Html5QrcodeScanner("qr-reader", { + fps: 2, + qrbox: qrboxFunction, + preferFrontCamera: false, + facingMode: { exact: "environment" }, + useBarCodeDetectorIfSupported: true, + }, true); + scanner.render(onScanSuccess); + + // Delay to ensure the element exists before adding the event + window.setTimeout(function() { + $('#html5-qrcode-button-camera-stop').on("click", function() { + $('#qr-reader').toggle(); + }); + }, 500); + }); }); -function submitData(){ - $(".alert").remove() +function submitData() { + $(".alert").remove(); $.ajax({ - method: "POST", - url: '/signintoEvent', - data: { - "eventid": $("#eventid").val(), - "bNumber": $("#submitScannerData").val() - }, - - success: function(resultID) { - if (resultID.status == "already signed in") { - msgFlash(`${resultID.user} already signed in!`, "warning"); - } else if (resultID.status === "banned") { - msgFlash(`${resultID.user} is ineligible!`, "danger"); - } else if (resultID.status === "does not exist") { - msgFlash("User does not exist", "danger"); - } else { - msgFlash(`${resultID.user} successfully signed in!`, "success"); + method: "POST", + url: '/signintoEvent', + data: { + "eventid": $("#eventid").val(), + "bNumber": $("#submitScannerData").val() + }, + success: function(resultID) { + if (resultID.status == "already signed in") { + msgFlash(`${resultID.user} already signed in!`, "warning"); + } else if (resultID.status === "banned") { + msgFlash(`${resultID.user} is ineligible!`, "danger"); + } else if (resultID.status === "does not exist") { + msgFlash("User does not exist", "danger"); + } else { + msgFlash(`${resultID.user} successfully signed in!`, "success"); + } + $("#submitScannerData").val("").blur(); + }, + error: function(request, status, error) { + console.log(status, error); + msgFlash("See Attendant; Unable to sign in.", "danger"); + $("#submitScannerData").val("").blur(); } - $("#submitScannerData").val("").blur(); - }, - - error: function(request, status, error) { - console.log(status, error); - msgFlash("See Attendant; Unable to sign in.", "danger"); - $("#submitScannerData").val("").blur(); - } - }) + }); } /*function hideElements(hide) { From a9b2d1254100f8e302f1685a0cf2abb2dbac3cea Mon Sep 17 00:00:00 2001 From: vungc Date: Fri, 28 Jun 2024 13:31:16 -0400 Subject: [PATCH 097/473] calendars on the modal are working now --- app/static/js/createEvents.js | 33 ++-------------------------- app/templates/admin/createEvent.html | 3 +-- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index ccf156387..e7ed207d0 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -269,7 +269,6 @@ $(document).ready(function() { } else if (customStatus == undefined){ $("#customTableDiv").addClass('d-none');// this line add the display none button of bootstrap so that the end-date div disappears for recurring event - } }); @@ -281,7 +280,7 @@ $(document).ready(function() { }); let counterAdd = 0 // counter to add customized ids into the newly created slots - + let deleteId = [] $(".add_customevent").click(function(){ counterAdd += 1 let clonedCustom = $("#customEvent").clone();// this line clones the customEvent id div in the custom event modal on createEvent.html line 403 @@ -294,48 +293,26 @@ $(document).ready(function() { $(".extraSlots").append(clonedCustom) $("#customEvent" + counterAdd).children("div#delete_customevent").attr("id", "delete_customevent" + counterAdd) //this line finds the id delete_customevent within the parent customevent and change the id attribute $("#delete_customevent" + counterAdd).removeClass('d-none'); - - $('#calendarIconStart-' + counterAdd).click(function() { - console.log('ok') - $('#customDatePicker-'+ counterAdd).datepicker().datepicker('show'); - }); - clonedCustom.find(".delete_customevent").attr("id", "delete_customevent" + counterAdd).removeClass('d-none'); deleteId.push({id: "#delete_customevent" + counterAdd}) console.log("#delete_customevent" + counterAdd) console.log(deleteId) - - // Attach click handler for the delete button using event delegation - $(document).on("click", "#delete_customevent" + counterAdd, function() { - // Handle delete action here - $(this).closest("#customEvent" + counterAdd).remove(); - }); - }); - - - - // $(".extraSlots").children().each(function(index, element) { // let rowData = $.map($(element).find("input"), (el) => $(el).val()) // console.log("Data in row " + (index + 1) + ": " + rowData) // // Modify this to display or manipulate your data as needed // }); - - - - $(".delete_row").click(function(){ // delete function for the added row, it is still not working console.log("here in delete") let numbers= $(".delete_row").length console.log(numbers) }); - $("#allowPastStart").click(function() { var allowPast = $("#allowPastStart:checked").val() if (allowPast == 'on') { @@ -349,6 +326,7 @@ $(document).ready(function() { dateFormat:'mm-dd-yy' }); } + }); // everything except Chrome if (navigator.userAgent.indexOf("Chrome") == -1) { @@ -391,12 +369,6 @@ $(document).ready(function() { $(".startDate").click(function() { $("#startDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); }); - $(".customDate").click(function() { - $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); - }); - $(".customDate1").click(function() { - $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); - }); $(".endDate").click(function() { $("#endDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); @@ -418,7 +390,6 @@ $(document).ready(function() { } }); - var facilitatorArray = [] function callback(selectedFacilitator) { // JSON.parse is required to de-stringify the search results into a dictionary. diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 58fc6bdbe..8ac3d686c 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -423,11 +423,10 @@
-
-
From 352d0aaac701c1201db1ee2a54600d621a1bf880 Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Fri, 28 Jun 2024 18:51:41 +0000 Subject: [PATCH 098/473] custom toggle fixed --- app/static/js/createEvents.js | 9 ++++++--- app/templates/admin/createEvent.html | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index ccf156387..2ea39d999 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -88,6 +88,7 @@ function storingCustomEventAttributes() { eventDate: rowData[0], startTime: rowData[1], endTime: rowData[2] + }); }); @@ -268,8 +269,8 @@ $(document).ready(function() { $("#checkIsCustom").prop('checked', true); } else if (customStatus == undefined){ - $("#customTableDiv").addClass('d-none');// this line add the display none button of bootstrap so that the end-date div disappears for recurring event - + $("#customTableDiv").addClass('d-none'); + $('#modalCustom').modal('hide'); } }); @@ -277,7 +278,9 @@ $(document).ready(function() { $("#checkIsCustom").prop('checked', false); $('#nonCustomTime, #nonCustomDate').removeClass('d-none'); $("#customTableDiv").addClass('d-none'); - $('.extraSlots').empty();//this line remove the added custom event slots from appearing if the custom modal is toggle again + $('#modalCustom').modal('hide'); + $('.extraSlots').children().not(':first').remove(); + //$('.extraSlots').empty();//this line remove the added custom event slots from appearing if the custom modal is toggle again }); let counterAdd = 0 // counter to add customized ids into the newly created slots diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 58fc6bdbe..38010d65a 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -138,7 +138,7 @@

{{page_title}}

@@ -415,7 +415,7 @@
"); - + recurringTable.append(""); } }, error: function(error){ console.log(error) } }); - } - var save_button = document.getElementById('submitParticipant'); var modal = document.getElementById('modalCustom'); @@ -76,8 +73,6 @@ save_button.addEventListener('click', function() { $('#modalCustom').modal('hide'); }); - - function storingCustomEventAttributes() { let entries = []; $(".extraSlots").children().each(function(index, element) { @@ -88,7 +83,6 @@ function storingCustomEventAttributes() { eventDate: rowData[0], startTime: rowData[1], endTime: rowData[2] - }); }); @@ -283,62 +277,24 @@ $(document).ready(function() { //$('.extraSlots').empty();//this line remove the added custom event slots from appearing if the custom modal is toggle again }); + /*cloning the div with ID customEvent and cloning, changing the ID of each clone going up by 1. This also changes the ID of the delete_customEvent so that when the trash icon is clicked, + that specific row will be deleted*/ + let counterAdd = 0 // counter to add customized ids into the newly created slots - $(".add_customevent").click(function(){ counterAdd += 1 let clonedCustom = $("#customEvent").clone();// this line clones the customEvent id div in the custom event modal on createEvent.html line 403 clonedCustom.attr("id", "customEvent" + counterAdd) - clonedCustom.find("[id^='customDate']").attr("id", "customDate-" + counterAdd); - clonedCustom.find("[data-page-location]").attr("id", "customDatePicker-" + counterAdd); - clonedCustom.find("[data-page-location]").attr("data-page-location", counterAdd); - clonedCustom.find("[id^='calendarIconStart']").attr("id", "calendarIconStart-" + counterAdd); - clonedCustom.find("[id^='customDatePicker']").attr("id", "customDatePicker-" + counterAdd); + clonedCustom.find("#delete_customevent").attr("id", "delete_customevent" + counterAdd).removeClass('d-none'); $(".extraSlots").append(clonedCustom) - $("#customEvent" + counterAdd).children("div#delete_customevent").attr("id", "delete_customevent" + counterAdd) //this line finds the id delete_customevent within the parent customevent and change the id attribute - $("#delete_customevent" + counterAdd).removeClass('d-none'); - - $('#calendarIconStart-' + counterAdd).click(function() { - console.log('ok') - $('#customDatePicker-'+ counterAdd).datepicker().datepicker('show'); - }); - - clonedCustom.find(".delete_customevent").attr("id", "delete_customevent" + counterAdd).removeClass('d-none'); - - deleteId.push({id: "#delete_customevent" + counterAdd}) - console.log("#delete_customevent" + counterAdd) - console.log(deleteId) - - // Attach click handler for the delete button using event delegation - $(document).on("click", "#delete_customevent" + counterAdd, function() { - // Handle delete action here - $(this).closest("#customEvent" + counterAdd).remove(); + //this is so that the trash icon can be used to delete the event + clonedCustom.on("click", "[id^=delete_customevent]", function() { + var id = $(this).attr('id').match(/\d+/)[0]; // Extract the numeric part from the id + $("#customEvent" + id).remove(); }); - }); - - - - - // $(".extraSlots").children().each(function(index, element) { - // let rowData = $.map($(element).find("input"), (el) => $(el).val()) - // console.log("Data in row " + (index + 1) + ": " + rowData) - // // Modify this to display or manipulate your data as needed - // }); - - - - - - $(".delete_row").click(function(){ // delete function for the added row, it is still not working - console.log("here in delete") - let numbers= $(".delete_row").length - console.log(numbers) - }); - - $("#allowPastStart").click(function() { var allowPast = $("#allowPastStart:checked").val() if (allowPast == 'on') { @@ -394,18 +350,11 @@ $(document).ready(function() { $(".startDate").click(function() { $("#startDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); }); - $(".customDate").click(function() { - $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); - }); - $(".customDate1").click(function() { - $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); - }); $(".endDate").click(function() { $("#endDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); }); - $(".startDatePicker, .endDatePicker").change(function(){ if ( $(this).val() && $("#endDatePicker-" + $(this).data("page-location")).val()){ calculateRecurringEventFrequency(); @@ -421,7 +370,6 @@ $(document).ready(function() { } }); - var facilitatorArray = [] function callback(selectedFacilitator) { // JSON.parse is required to de-stringify the search results into a dictionary. @@ -463,9 +411,9 @@ $(document).ready(function() { updateDate(this) }); - $(".customDatePicker").change(function(){ //custom data calender function - updateDate(this) - }); +// $(".customDatePicker").change(function(){ //custom data calender function +// updateDate(this) +// }); $("#inputCharacters").keyup(function(event){ setCharacterLimit(this, "#remainingCharacters") From 809646b034d80e0a25445f45c1d84252a6bd5122 Mon Sep 17 00:00:00 2001 From: jahatehs Date: Fri, 28 Jun 2024 16:01:52 -0400 Subject: [PATCH 101/473] We made all changes suggested in the PR conversations. --- app/controllers/serviceLearning/routes.py | 1 - app/models/course.py | 2 -- app/models/courseStatus.py | 4 +--- app/templates/serviceLearning/slcProposal.html | 10 ++-------- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/app/controllers/serviceLearning/routes.py b/app/controllers/serviceLearning/routes.py index 1a404ad3c..caeb9782e 100644 --- a/app/controllers/serviceLearning/routes.py +++ b/app/controllers/serviceLearning/routes.py @@ -54,7 +54,6 @@ def slcEditProposal(courseID): if g.current_user.isCeltsAdmin or g.current_user in courseInstructors or isCourseCreator: course = Course.get_by_id(courseID) courseStatus = CourseStatus.get_by_id(course.status) - print("Type of courseStatus:", type(courseStatus)) courseStatusInt = courseStatus.get_id() approved = 3 # Condition to check the route you are comming from diff --git a/app/models/course.py b/app/models/course.py index ffa40ce89..a744ef9ec 100644 --- a/app/models/course.py +++ b/app/models/course.py @@ -1,9 +1,7 @@ from app.models import * from app.models.term import Term from app.models.courseStatus import CourseStatus -from app.models.note import Note from app.models.user import User -from peewee import CharField, FloatField, BooleanField, ForeignKeyField, TextField class Course(baseModel): courseName = CharField() diff --git a/app/models/courseStatus.py b/app/models/courseStatus.py index faea58315..126114c5e 100644 --- a/app/models/courseStatus.py +++ b/app/models/courseStatus.py @@ -1,6 +1,4 @@ -# from app.models import* -from app.models import baseModel -from peewee import CharField +from app.models import* class CourseStatus(baseModel): diff --git a/app/templates/serviceLearning/slcProposal.html b/app/templates/serviceLearning/slcProposal.html index 2946ed510..8ede5ac19 100644 --- a/app/templates/serviceLearning/slcProposal.html +++ b/app/templates/serviceLearning/slcProposal.html @@ -1,9 +1,7 @@

Proposal For Service-Learning Course

-

Proposal Status: - - {{ courseStatus.status }} - +

Status: + {{ courseStatus.status }}

Please review the service-learning course guidelines before completing this form

@@ -205,7 +203,3 @@

Proposal Status: - - - - From 9fe0da00affb3154cc521476412a88acd7b8cf89 Mon Sep 17 00:00:00 2001 From: dea Date: Fri, 28 Jun 2024 16:14:06 -0400 Subject: [PATCH 102/473] Fixed table --- app/logic/serviceLearningCourses.py | 33 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 4a4ec6616..cb56bfaca 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -60,11 +60,32 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li if 'errorMsg' in courseInfo and courseInfo['errorMsg']: print(f"Unable to save course {course}. {courseInfo['errorMsg']}") continue + # Look in the db for a course that matches abbreviation and term (query that returns one course) + # If matches, use this course to add participants - check_for_Existing_Courses = list((Course.select().where(Course.courseAbbreviation == course ).order_by(Course.term.desc()).limit(1))) + # If no match + # Select most recent course whose abbreviations match, but term is before the term we are trying to import for (termorder is LESS) + # If this course exists, use this course + # If this course does not exist, create a new course + # Add participants to desired course from the database - if not check_for_Existing_Courses : + termCheck = Term.get(Term.id == termObj) + + checkTermOrder = termCheck.termOrder + + print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") + + print(checkTermOrder) + + check_for_Existing_Courses = list((Course.select() + .join(Term, on =(Course.term == Term.id)) + .where((Course.courseAbbreviation == course) & (Term.termOrder < checkTermOrder)) + .order_by(Course.term.desc()) + .limit(1))) + + + if not check_for_Existing_Courses: courseObj: Course = Course.create(courseName = "", sectionDesignation = "", @@ -75,12 +96,12 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li createdBy = g.current_user, serviceLearningDesignatedSections = "", previouslyApprovedDescription = "" ) - - elif termObj == check_for_Existing_Courses[0].term: - print("The course already exists") + elif Term.termOrder == checkTermOrder : - else : + print("###################################################") + + else: previous_data = check_for_Existing_Courses[0] From 2b2593ca4f35eb2b8f1f4a46d0128d3fb3671762 Mon Sep 17 00:00:00 2001 From: Brian Ramsay Date: Fri, 28 Jun 2024 17:10:13 -0400 Subject: [PATCH 103/473] let students update themselves --- app/controllers/main/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/main/routes.py b/app/controllers/main/routes.py index 7b0832a35..6a264fa5c 100644 --- a/app/controllers/main/routes.py +++ b/app/controllers/main/routes.py @@ -488,7 +488,7 @@ def getDietInfo(): @main_bp.route('/profile//indicateInterest', methods=['POST']) def indicateMinorInterest(username): - if g.current_user.isCeltsAdmin: + if g.current_user.isCeltsAdmin or g.current_user.username == username: toggleMinorInterest(username) else: From aecd78d472f1f9759d0fc64f5df1f9b60b92fff4 Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Sun, 30 Jun 2024 15:13:56 +0000 Subject: [PATCH 104/473] added event name in front end --- app/templates/admin/createEvent.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 977d53bf8..9aab28afa 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -419,7 +419,16 @@
-
+
+ +
+ + +
+ + + +
From f1ccb17b123c37f84552840eaf06b0f310e0f3af Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Mon, 1 Jul 2024 11:45:48 +0000 Subject: [PATCH 105/473] custom table completed --- app/controllers/admin/routes.py | 1 + app/static/js/createEvents.js | 9 +++++---- app/templates/admin/createEvent.html | 10 +++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 4c665e630..e148a3c8a 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -104,6 +104,7 @@ def createEvent(templateid, programid): except Exception as e: print("Error saving event:", e) savedEvents = False + validationErrorMessage = "Unknown Error Saving Event. Please try again" if savedEvents: diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index 21341e6f0..8b44672f2 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -80,9 +80,10 @@ function storingCustomEventAttributes() { console.log("Data in row " + (index + 1) + ": " + rowData); entries.push({ - eventDate: rowData[0], - startTime: rowData[1], - endTime: rowData[2] + eventName: rowData[0], + eventDate: rowData[1], + startTime: rowData[2], + endTime: rowData[3] }); }); @@ -95,7 +96,7 @@ function storingCustomEventAttributes() { console.log(customTable) entries.forEach(function(entry){ - customTable.append("

"); + customTable.append(""); }); } diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 9aab28afa..f25346ee1 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -64,9 +64,9 @@

{{page_title}}

- +
@@ -421,10 +421,10 @@

-
+
-
+
From 451e9ddced8f857399985786d11d4b34064b6bfc Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Mon, 1 Jul 2024 14:46:06 +0000 Subject: [PATCH 106/473] hidden input created --- app/static/js/createEvents.js | 4 ++++ app/templates/admin/createEvent.html | 1 + 2 files changed, 5 insertions(+) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index 8b44672f2..6dabec6c4 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -90,6 +90,10 @@ function storingCustomEventAttributes() { console.log(entries); console.log(typeof entires) + let entriesJson = JSON.stringify(entries); + document.getElementById("customEventsDataId").value = entriesJson + + var customTable = $("#customEventsTable"); console.log(customTable) customTable.find("tbody tr").remove(); // Clear existing rows diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index f25346ee1..57d1cc559 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -193,6 +193,7 @@

{{page_title}}

- - {{ shortName }}
" + event.name + "" + entry.eventDate +"" + entry.startTime + "" + entry.endTime + "
"+event.name+""+eventdate+""+startTime+""+endTime+"
" + event.name + "" + eventDate + "" + startTime + "" + endTime + "
" + event.name + "" + entry.eventDate +"" + entry.startTime + "" + entry.endTime + "
"+event.name+""+eventdate+"
"+event.name+""+eventdate+"
" + event.name + "" + entry.eventDate +"" + entry.startTime + "" + entry.endTime + "
" + entry.eventName + "" + entry.eventDate +"" + entry.startTime + "" + entry.endTime + "
+ {% if 'program' in eventData and eventData['program'].isBonnerScholars %}
From ade2d322fedce70fdef59a26ad2d6a14fcc84c8d Mon Sep 17 00:00:00 2001 From: CollegeStevenLN <156225590+CollegeStevenLN@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:33:29 -0400 Subject: [PATCH 107/473] made the two remaining changes from the PR comments --- app/controllers/serviceLearning/routes.py | 2 +- app/static/js/slcNewProposal.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/serviceLearning/routes.py b/app/controllers/serviceLearning/routes.py index a9a8c2244..6f2eb9a19 100644 --- a/app/controllers/serviceLearning/routes.py +++ b/app/controllers/serviceLearning/routes.py @@ -93,7 +93,7 @@ def slcCancelProposal(): courseID = request.form.get('courseID') course = Course.get_by_id(courseID) if not course.courseName and not course.courseAbbreviation: - CourseQuestion.delete().where(CourseQuestion.course_id == courseID).execute() + CourseQuestion.delete().where(CourseQuestion.course == course).execute() course.delete_instance() return "Proposal Canceled" diff --git a/app/static/js/slcNewProposal.js b/app/static/js/slcNewProposal.js index 8bab2027f..af24ef676 100644 --- a/app/static/js/slcNewProposal.js +++ b/app/static/js/slcNewProposal.js @@ -78,13 +78,13 @@ $(document).ready(function(e) { }); $("#cancelButton").on("click", function() { - var cancelButtonContext = this + var cancelButton = $(this) $.ajax({ url: '/serviceLearning/canceledProposal', method: 'POST', data: {courseID : document.getElementById('courseID').value}, success: function(response) { - window.location.replace($(cancelButtonContext).val()); + window.location.replace(cancelButton.val()); } }) }); From ec4054a180dcca8da7d5023ecca1b9e723337bf2 Mon Sep 17 00:00:00 2001 From: jahatehs Date: Mon, 1 Jul 2024 15:22:38 -0400 Subject: [PATCH 108/473] Reduced the size of 'select box', used built-in bootstrap for styling the 'select box' and 'label', and renamed the download button to 'Download' and moved the Excel icon infront of the name. --- app/templates/admin/reports.html | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/app/templates/admin/reports.html b/app/templates/admin/reports.html index 4d491235a..b1445ba92 100644 --- a/app/templates/admin/reports.html +++ b/app/templates/admin/reports.html @@ -3,25 +3,32 @@ {% block app_content %} -
+

Download Annual Report

-
-
- - + +
+
+ +
+
+ +
+
+ +
+
-
- - -
+
{% endblock %} \ No newline at end of file From b180dfa496131631c4b1279e402e3d20d190b14c Mon Sep 17 00:00:00 2001 From: zawn Date: Mon, 1 Jul 2024 15:55:30 -0400 Subject: [PATCH 109/473] is able to toggle the button with F11 and Esc and back button is done correctly good UI/UX design --- app/static/js/eventKiosk.js | 4 +++- app/templates/events/eventKiosk.html | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index 4c4ca7e46..0788c227a 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -2,7 +2,7 @@ var elem = document.getElementById("show"); $(document).on("fullscreenchange", function() { if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { - closeFullscreen(false); // Pass false to indicate not to toggle button text + closeFullscreen(true); // Pass false to indicate not to toggle button text } }); @@ -41,6 +41,8 @@ function openFullscreen() { elem.msRequestFullscreen(); } ensureFocus(); + + $("#fullscreenCheck").attr("onclick", "toggleFullscreen()").text("Close Full Screen"); } diff --git a/app/templates/events/eventKiosk.html b/app/templates/events/eventKiosk.html index 2b1df681e..9a95f2061 100644 --- a/app/templates/events/eventKiosk.html +++ b/app/templates/events/eventKiosk.html @@ -26,9 +26,9 @@

{{ bNumberToUser }}

- Back + Back
-
+
From f188cb8fbc742483563b086e703867255debc10f Mon Sep 17 00:00:00 2001 From: vungc Date: Mon, 1 Jul 2024 20:48:00 +0000 Subject: [PATCH 110/473] added for loop in the routes to create dictioanries for each of the multiple events --- app/controllers/admin/routes.py | 40 ++++++++++++++++++++++++++++++++- app/logic/events.py | 32 +++++++++++++------------- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index e148a3c8a..3cca1de54 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -5,6 +5,7 @@ import json from datetime import datetime import os +import ast from app import app from app.models.program import Program @@ -98,8 +99,45 @@ def createEvent(templateid, programid): # Try to save the form if request.method == "POST": eventData.update(request.form.copy()) + print(eventData['isCustom']) + print('################################################################################') + print(eventData) + print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") + print(eventData['customEventsData']) + # print(type(eventData['customEventsData'][0])) + if eventData['isCustom']: + customEventsList = [] + for event in ast.literal_eval(eventData['customEventsData']): + # event = dict(event) + customDict = { + 'name': event['eventName'], + 'term': eventData['term'], + 'isCustom': eventData['isCustom'], + 'location': eventData['location'], + 'startDate': event['eventDate'], + 'endDate': eventData['endDate'], + 'timeStart': event['startTime'], + 'timeEnd': event['endTime'], + 'description': eventData['description'], + 'contactName':eventData['contactName'], + 'contactEmail': eventData['contactEmail'], + 'isRsvpRequired': eventData.get('isRsvpRequired'), + 'isTraining': eventData.get('isTraining'), + 'rsvpLimit': eventData.get('rsvpLimit'), + 'isFoodProvided': eventData.get('isFoodProvided'), + 'isService': eventData.get('isService'), + 'attachmentObject': eventData.get('attachmentObject') + } + customEventsList.append(customDict) + print('78787r7457575757575757777777777777777777') + print(customDict) + try: - savedEvents, validationErrorMessage = attemptSaveEvent(eventData, getFilesFromRequest(request)) + if eventData['isCustom']: + for customEvent in customEventsList: + savedEvents, validationErrorMessage = attemptSaveEvent(customEvent, getFilesFromRequest(request)) + else: + savedEvents, validationErrorMessage = attemptSaveEvent(eventData, getFilesFromRequest(request)) except Exception as e: print("Error saving event:", e) diff --git a/app/logic/events.py b/app/logic/events.py index 596ebfe22..8aa7d13d7 100644 --- a/app/logic/events.py +++ b/app/logic/events.py @@ -460,23 +460,6 @@ def calculateRecurringEventFrequency(event): "week": counter+1} for counter in range(0, ((event['endDate']-event['startDate']).days//7)+1)] -# def calculateCustomEventFrequency(event): -# """ -# Calculate the events to create based on the different dates and times provided. Takes a -# dictionary of event data. - -# Assumes that the data has been processed with `preprocessEventData`. NOT raw form data. - -# Return a list of events to create from the event data. -# """ -# if not isinstance(event['endDate'], date) or not isinstance(event['startDate'], date): -# raise Exception("startDate and endDate must be datetime.date objects.") - -# return [ {'name': f"{event['name']}", -# 'date': event['startDate'] + timedelta(days=7*counter), -# "week": counter+1} -# for counter in range(0, ((event['endDate']-event['startDate']).days//7)+1)] - def preprocessEventData(eventData): """ Ensures that the event data dictionary is consistent before it reaches the template or event logic. @@ -496,6 +479,21 @@ def preprocessEventData(eventData): else: eventData[checkBox] = bool(eventData[checkBox]) + # if eventData['isCustom']: + # if 'customEventsData' in eventData: #this should not exist anymore if the list of dictionaries have been processed once already + # customEventsList = [] + # for event in eventData['customEventsData']: + # customDict = { + # 'name': event['eventName'], + # 'startDate': event['eventDate'], + # 'timeStart': event['startTime'], + # 'timeEnd': event['endTime'] + # } + # customEventsList.append(customDict) + # for customEvents in customEventsList: + # processedCustomEvents = preprocessEventData(customEvents) + + ## Process dates eventDates = ['startDate', 'endDate'] for eventDate in eventDates: From fd02495394a5608aa1165d9e7c0f6b67702d5df5 Mon Sep 17 00:00:00 2001 From: Josh Wakin Date: Tue, 2 Jul 2024 09:04:54 -0400 Subject: [PATCH 111/473] Added a elif statement to check if imported course s are in the same semester --- app/logic/serviceLearningCourses.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index cb56bfaca..fdb50e01f 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -73,10 +73,11 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li termCheck = Term.get(Term.id == termObj) checkTermOrder = termCheck.termOrder + #dosnt work + CurrentTermOrder = Term.termOrder - print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") - print(checkTermOrder) + check_for_Existing_Courses = list((Course.select() .join(Term, on =(Course.term == Term.id)) @@ -84,8 +85,10 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li .order_by(Course.term.desc()) .limit(1))) - - if not check_for_Existing_Courses: + + if not check_for_Existing_Courses : + + courseObj: Course = Course.create(courseName = "", sectionDesignation = "", @@ -96,10 +99,15 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li createdBy = g.current_user, serviceLearningDesignatedSections = "", previouslyApprovedDescription = "" ) - - elif Term.termOrder == checkTermOrder : - - print("###################################################") + + #peewee dosnt throw an error, always returns true + elif CurrentTermOrder == checkTermOrder: + print('################################################') + print(CurrentTermOrder) + print(checkTermOrder) + courseObj : Course = Course.get( courseAbbreviation = course, + term = termObj) + else: From 19614046b698cf0b99fd4e23761c603145f72b89 Mon Sep 17 00:00:00 2001 From: vungc Date: Tue, 2 Jul 2024 13:40:46 +0000 Subject: [PATCH 112/473] chagned time displayed to be in 12hr format, cleaned up HTML and JS files --- app/controllers/admin/routes.py | 10 +++++----- app/static/js/createEvents.js | 21 ++++++------------- app/templates/admin/createEvent.html | 30 ++-------------------------- 3 files changed, 13 insertions(+), 48 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 3cca1de54..33af61de0 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -99,20 +99,20 @@ def createEvent(templateid, programid): # Try to save the form if request.method == "POST": eventData.update(request.form.copy()) - print(eventData['isCustom']) + print(eventData.get('isCustom')) print('################################################################################') print(eventData) print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") - print(eventData['customEventsData']) + print(eventData.get('customEventsData')) # print(type(eventData['customEventsData'][0])) - if eventData['isCustom']: + if eventData.get('isCustom'): customEventsList = [] - for event in ast.literal_eval(eventData['customEventsData']): + for event in ast.literal_eval(eventData.get('customEventsData')): # event = dict(event) customDict = { 'name': event['eventName'], 'term': eventData['term'], - 'isCustom': eventData['isCustom'], + 'isCustom': eventData.get('isCustom'), 'location': eventData['location'], 'startDate': event['eventDate'], 'endDate': eventData['endDate'], diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index 6dabec6c4..d59a6e387 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -61,11 +61,7 @@ function format24to12HourTime(timeStr){ }); } - var save_button = document.getElementById('submitParticipant'); - var modal = document.getElementById('modalCustom'); - -// Assuming save_button is properly defined elsewhere in your code -save_button.addEventListener('click', function() { + document.getElementById('submitParticipant').addEventListener('click', function() { // Call the function storingCustomEventAttributes() when the button is clicked storingCustomEventAttributes(); $("#checkIsCustom").prop('checked', true); @@ -93,20 +89,16 @@ function storingCustomEventAttributes() { let entriesJson = JSON.stringify(entries); document.getElementById("customEventsDataId").value = entriesJson - var customTable = $("#customEventsTable"); - console.log(customTable) customTable.find("tbody tr").remove(); // Clear existing rows - console.log(customTable) entries.forEach(function(entry){ - - customTable.append("" + entry.eventName + "" + entry.eventDate +"" + entry.startTime + "" + entry.endTime + ""); + //fromat to 12hr time for display + var startTime = format24to12HourTime(entry.startTime); + var endTime = format24to12HourTime(entry.endTime); + customTable.append("" + entry.eventName + "" + entry.eventDate +"" + startTime + "" + endTime + ""); }); - } - - // $.ajax({ // type: "POST", // url: "/makeCustomEvents", @@ -234,7 +226,6 @@ $(document).ready(function() { if ( $(".startDatePicker")[0].value != $(".endDatePicker")[0].value){ calculateRecurringEventFrequency(); } - handleFileSelection("attachmentObject") $("#checkRSVP").on("click", function() { @@ -284,7 +275,6 @@ $(document).ready(function() { /*cloning the div with ID customEvent and cloning, changing the ID of each clone going up by 1. This also changes the ID of the delete_customEvent so that when the trash icon is clicked, that specific row will be deleted*/ - let counterAdd = 0 // counter to add customized ids into the newly created slots $(".add_customevent").click(function(){ counterAdd += 1 @@ -314,6 +304,7 @@ $(document).ready(function() { }); } }); + // everything except Chrome if (navigator.userAgent.indexOf("Chrome") == -1) { $('input.timepicker').timepicker({ diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 57d1cc559..1823bc069 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -64,7 +64,7 @@

{{page_title}}

-
@@ -72,7 +72,6 @@

{{page_title}}

-
@@ -185,16 +184,13 @@

{{page_title}}

-
Event NameDateStart TimeEnd Time
- - {% if 'program' in eventData and eventData['program'].isBonnerScholars %}
@@ -329,7 +325,6 @@
- - -
- - - - - - - - {% endblock %} From 6e75ad04b5f2f760a497e1f1247aa06b5534ea16 Mon Sep 17 00:00:00 2001 From: zawn Date: Tue, 2 Jul 2024 10:29:14 -0400 Subject: [PATCH 113/473] delted unecessary comments --- app/static/js/eventKiosk.js | 77 +------------------------------------ 1 file changed, 2 insertions(+), 75 deletions(-) diff --git a/app/static/js/eventKiosk.js b/app/static/js/eventKiosk.js index 0788c227a..653553514 100644 --- a/app/static/js/eventKiosk.js +++ b/app/static/js/eventKiosk.js @@ -2,7 +2,7 @@ var elem = document.getElementById("show"); $(document).on("fullscreenchange", function() { if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { - closeFullscreen(true); // Pass false to indicate not to toggle button text + closeFullscreen(true); } }); @@ -15,7 +15,7 @@ $(document).keydown(function(e) { function toggleFullscreen() { if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { - closeFullscreen(true); // Pass true to indicate toggling button text + closeFullscreen(true); } else { openFullscreen(); } @@ -162,76 +162,3 @@ function submitData() { }); } -/*function hideElements(hide) { - if (hide == true) { - $("col-md-auto d-print-none d-lg-none").css("width", "0"); - $("footer").hide(); - $("kiosk-hide").animate({ opacity: 0 }, 1); - $("kiosk-hide").css("width", "0"); - $("kiosk-hide").prop("disabled", true); - $("position-fixed float-start").hide(); - $("position-fixed float-start").css("width", "0"); - $("#sideBarContainer").attr("class", "col-md-0 d-print-none d-none d-lg-block") - $("#sideBar").attr("class", "position-fixed float-start d-none") - $("#sideBarSandwichUI").attr("class","btn btn-dark rounded-0 rounded-end kiosk-hide d-none") - } else - { - console.log("in hide element before keydown") - $("footer").show(); - $("kiosk-hide").css("width", "inherit"); - $("kiosk-hide").animate({ opacity: 1 }, 1); - $("kiosk-hide").prop("disabled", false); - $("a").show(); - $("#sideBarContainer").attr("class", "col-md-auto d-print-none d-none d-lg-block") - $("#sideBar").attr("class", "position-fixed float-start") - $("#sideBarSandwichUI").attr("class","btn btn-dark rounded-0 rounded-end kiosk-hide") - console.log("in hide element after keydown") - } -} - -// Source: https://stackoverflow.com/questions/1125084/how-to-make-the-window-full-screen-with-javascript-stretching-all-over-the-screen -function toggleFullscreen() { - if($("#fullscreenCheck").prop("checked") == true){ - hideElements(true); - var el = document.documentElement - , rfs = // for newer Webkit and Firefox - el.requestFullscreen - || el.webkitRequestFullScreen - || el.mozRequestFullScreen - || el.msRequestFullscreen - ; - - if(typeof rfs!="undefined" && rfs){ - rfs.call(el); - exited = false - - }else if(typeof window.ActiveXObject!="undefined"){ - // for Internet Explorer - exited = false - - var wscript = new ActiveXObject("WScript.Shell"); - if (wscript!=null) { - exited = false - - wscript.SendKeys("{F11}"); - } - } - }else if ($("#fullscreenCheck").prop("checked") == false){ - hideElements(false); - document.exitFullscreen() || document.webkitExitFullscreen() || document.msExitFullscreen() - } - $('#submitScannerData').focus(); - -}; -/* if (document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { - console.log("Fullscreen mode was entered"); - hideElements(true); - console.log("here wewe") -} else { - console.log("Fullscreen mode was exited"); -}if (!document.fullscreenElement && !document.webkitFullscreenElement && !document.mozFullScreenElement && !document.msFullscreenElement) { - console.log("Fullscreen mode was exited"); -}*/ - - - From 52b88e2a4eb0c70fc66b122fc158d718d21e84d7 Mon Sep 17 00:00:00 2001 From: vungc Date: Tue, 2 Jul 2024 15:38:57 +0000 Subject: [PATCH 114/473] tried to debug the dicitoanry in the routes, still work in progress --- app/controllers/admin/routes.py | 36 +++++++++++++++++----------- app/static/js/createEvents.js | 10 +++++--- app/templates/admin/createEvent.html | 4 ++-- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 33af61de0..d24d99753 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -6,6 +6,7 @@ from datetime import datetime import os import ast +from dateutil.parser import parse from app import app from app.models.program import Program @@ -108,19 +109,26 @@ def createEvent(templateid, programid): if eventData.get('isCustom'): customEventsList = [] for event in ast.literal_eval(eventData.get('customEventsData')): + print('hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh') + print(type(event['startTime'])) + print(type(event['endTime'])) + print(event['eventDate']) + customDate = parse(event.get('eventDate')).date() + customStartTime = datetime.strptime(event.get('startTime'), '%H:%M').time() + customEndTime = datetime.strptime(event.get('endTime'), '%H:%M').time() # event = dict(event) customDict = { - 'name': event['eventName'], - 'term': eventData['term'], + 'name': event.get('eventName'), + 'term': eventData.get('term'), 'isCustom': eventData.get('isCustom'), - 'location': eventData['location'], - 'startDate': event['eventDate'], - 'endDate': eventData['endDate'], - 'timeStart': event['startTime'], - 'timeEnd': event['endTime'], - 'description': eventData['description'], - 'contactName':eventData['contactName'], - 'contactEmail': eventData['contactEmail'], + 'location': eventData.get('location'), + 'startDate': customDate, + 'endDate': eventData.get('endDate'), + 'timeStart': customStartTime, + 'timeEnd': customEndTime, + 'description': eventData.get('description'), + 'contactName':eventData.get('contactName'), + 'contactEmail': eventData.get('contactEmail'), 'isRsvpRequired': eventData.get('isRsvpRequired'), 'isTraining': eventData.get('isTraining'), 'rsvpLimit': eventData.get('rsvpLimit'), @@ -413,10 +421,10 @@ def addRecurringEvents(): recurringEvents = calculateRecurringEventFrequency(preprocessEventData(request.form.copy())) return json.dumps(recurringEvents, default=str) -@admin_bp.route('/makeCustomEvents', methods=['POST']) -def addCustomEvents(): - customEvents = preprocessEventData(request.form.copy()) - return json.dumps(customEvents, default=str) +# @admin_bp.route('/makeCustomEvents', methods=['POST']) +# def addCustomEvents(): +# customEvents = preprocessEventData(request.form.copy()) +# return json.dumps(customEvents, default=str) diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index d59a6e387..e0da69bf3 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -357,6 +357,10 @@ $(document).ready(function() { } }); + $(".customDate").click(function() { + $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); + }); + $("#checkRSVP").click(function(){ if ($("input[name='isRsvpRequired']:checked").val() == 'on'){ $("#checkFood").prop('checked', true); @@ -407,9 +411,9 @@ $(document).ready(function() { updateDate(this) }); -// $(".customDatePicker").change(function(){ //custom data calender function -// updateDate(this) -// }); + $(".customDatePicker").change(function(){ //custom data calender function + updateDate(this) + }); $("#inputCharacters").keyup(function(event){ setCharacterLimit(this, "#remainingCharacters") diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 1823bc069..5f52f9e3f 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -419,11 +419,11 @@
-
- +
From e7273acb8224d970a0ff8a6ba76951cb443bcc3d Mon Sep 17 00:00:00 2001 From: dea Date: Tue, 2 Jul 2024 13:47:11 -0400 Subject: [PATCH 115/473] Issue fixed. Added queries to filter out duplicate course + checks forsame course and term and puts pparticipants into existing courses. --- app/logic/serviceLearningCourses.py | 52 +++++++++++++---------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index fdb50e01f..68252b5e7 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -74,22 +74,18 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li checkTermOrder = termCheck.termOrder #dosnt work - CurrentTermOrder = Term.termOrder - - - - + check_for_Existing_Courses = list((Course.select() .join(Term, on =(Course.term == Term.id)) - .where((Course.courseAbbreviation == course) & (Term.termOrder < checkTermOrder)) + .where((Course.courseAbbreviation == course) & (Term.termOrder <= checkTermOrder)) .order_by(Course.term.desc()) .limit(1))) + + if not check_for_Existing_Courses : - - courseObj: Course = Course.create(courseName = "", sectionDesignation = "", courseAbbreviation = course, @@ -98,30 +94,28 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li status = 4, createdBy = g.current_user, serviceLearningDesignatedSections = "", - previouslyApprovedDescription = "" ) - - #peewee dosnt throw an error, always returns true - elif CurrentTermOrder == checkTermOrder: - print('################################################') - print(CurrentTermOrder) - print(checkTermOrder) - courseObj : Course = Course.get( courseAbbreviation = course, - term = termObj) - - + previouslyApprovedDescription = "") + else: - previous_data = check_for_Existing_Courses[0] - courseObj: Course = Course.create(courseName = previous_data.courseName, - courseAbbreviation = previous_data.courseAbbreviation, - sectionDesignation = previous_data.sectionDesignation, - courseCredit = 1, - term = termObj, - status = 4, - createdBy = g.current_user, - serviceLearningDesignatedSections = previous_data.serviceLearningDesignatedSections, - previouslyApprovedDescription = previous_data.previouslyApprovedDescription) + currentTerm = Term.get(Term.id == previous_data.term) + + + if (currentTerm.termOrder) == checkTermOrder: + print("##########################################################################") + courseObj : Course = Course.get( courseAbbreviation = course, term = termObj) + + else: + courseObj: Course = Course.create(courseName = previous_data.courseName, + courseAbbreviation = previous_data.courseAbbreviation, + sectionDesignation = previous_data.sectionDesignation, + courseCredit = 1, + term = termObj, + status = 4, + createdBy = g.current_user, + serviceLearningDesignatedSections = previous_data.serviceLearningDesignatedSections, + previouslyApprovedDescription = previous_data.previouslyApprovedDescription) for userDict in courseInfo['students']: if userDict['errorMsg']: From 2f831158f8ce859938a55ddec7bf64035aa30145 Mon Sep 17 00:00:00 2001 From: dea Date: Tue, 2 Jul 2024 13:59:58 -0400 Subject: [PATCH 116/473] Issue fixed. Added queries to filter out duplicate course + checks forsame course and term and puts pparticipants into existing courses and comments deleted --- app/logic/serviceLearningCourses.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/app/logic/serviceLearningCourses.py b/app/logic/serviceLearningCourses.py index 68252b5e7..98a12b5d5 100644 --- a/app/logic/serviceLearningCourses.py +++ b/app/logic/serviceLearningCourses.py @@ -60,30 +60,17 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li if 'errorMsg' in courseInfo and courseInfo['errorMsg']: print(f"Unable to save course {course}. {courseInfo['errorMsg']}") continue - # Look in the db for a course that matches abbreviation and term (query that returns one course) - # If matches, use this course to add participants - - # If no match - # Select most recent course whose abbreviations match, but term is before the term we are trying to import for (termorder is LESS) - # If this course exists, use this course - # If this course does not exist, create a new course - - # Add participants to desired course from the database termCheck = Term.get(Term.id == termObj) checkTermOrder = termCheck.termOrder - #dosnt work - + check_for_Existing_Courses = list((Course.select() .join(Term, on =(Course.term == Term.id)) .where((Course.courseAbbreviation == course) & (Term.termOrder <= checkTermOrder)) .order_by(Course.term.desc()) .limit(1))) - - - if not check_for_Existing_Courses : courseObj: Course = Course.create(courseName = "", @@ -103,7 +90,6 @@ def saveCourseParticipantsToDatabase(cpPreview: Dict[str, Dict[str, Dict[str, Li if (currentTerm.termOrder) == checkTermOrder: - print("##########################################################################") courseObj : Course = Course.get( courseAbbreviation = course, term = termObj) else: From c5de53fd313f0ab07ae7882bca58e756d90d7021 Mon Sep 17 00:00:00 2001 From: CollegeStevenLN <156225590+CollegeStevenLN@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:00:55 -0400 Subject: [PATCH 117/473] changed from form-control to form-select --- app/templates/admin/reports.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/admin/reports.html b/app/templates/admin/reports.html index b1445ba92..c07977e55 100644 --- a/app/templates/admin/reports.html +++ b/app/templates/admin/reports.html @@ -11,7 +11,7 @@

Download Annual Report

- {% for year in academicYears %} From 5e6e54644080bd4255b637ea849d7593917265b4 Mon Sep 17 00:00:00 2001 From: Anupriya Dixit Date: Tue, 2 Jul 2024 22:49:09 +0000 Subject: [PATCH 118/473] json error fixed --- app/controllers/admin/routes.py | 69 ++++++++++++++++------------ app/static/js/createEvents.js | 12 ++--- app/templates/admin/createEvent.html | 4 +- app/templates/base.html | 3 +- 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index d24d99753..30c4d2277 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -108,50 +108,61 @@ def createEvent(templateid, programid): # print(type(eventData['customEventsData'][0])) if eventData.get('isCustom'): customEventsList = [] + + # print(rsvp_limit) + for event in ast.literal_eval(eventData.get('customEventsData')): print('hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh') print(type(event['startTime'])) print(type(event['endTime'])) - print(event['eventDate']) - customDate = parse(event.get('eventDate')).date() - customStartTime = datetime.strptime(event.get('startTime'), '%H:%M').time() - customEndTime = datetime.strptime(event.get('endTime'), '%H:%M').time() + print(type(event['eventDate'])) + print(type(eventData['endDate'])) + print(eventData['rsvpLimit']) + print(type(eventData['rsvpLimit'])) + print(eventData.get("rsvpLimit") != "") # event = dict(event) customDict = { - 'name': event.get('eventName'), - 'term': eventData.get('term'), - 'isCustom': eventData.get('isCustom'), - 'location': eventData.get('location'), - 'startDate': customDate, - 'endDate': eventData.get('endDate'), - 'timeStart': customStartTime, - 'timeEnd': customEndTime, - 'description': eventData.get('description'), - 'contactName':eventData.get('contactName'), - 'contactEmail': eventData.get('contactEmail'), + 'program': eventData['program'], + 'name': event['eventName'], + 'term': eventData['term'], + 'isCustom': eventData['isCustom'], + 'location': eventData['location'], + 'startDate': event['eventDate'], + 'timeStart': event['startTime'], + 'timeEnd': event['endTime'], + 'description': eventData['description'], + 'contactName':eventData['contactName'], + 'contactEmail': eventData['contactEmail'], 'isRsvpRequired': eventData.get('isRsvpRequired'), 'isTraining': eventData.get('isTraining'), - 'rsvpLimit': eventData.get('rsvpLimit'), + 'rsvpLimit': None if eventData.get("rsvpLimit") == "" else int(eventData.get("rsvpLimit")), 'isFoodProvided': eventData.get('isFoodProvided'), 'isService': eventData.get('isService'), 'attachmentObject': eventData.get('attachmentObject') } - customEventsList.append(customDict) - print('78787r7457575757575757777777777777777777') - print(customDict) + try: + savedEvents, validationErrorMessage = attemptSaveEvent(customDict, getFilesFromRequest(request)) + except Exception as e: + print("Failed saving multi event", e) + # customEventsList.append(customDict) + + print('################################################################') + print(customDict) - try: - if eventData['isCustom']: - for customEvent in customEventsList: - savedEvents, validationErrorMessage = attemptSaveEvent(customEvent, getFilesFromRequest(request)) - else: + # try: + # if eventData.get('isCustom'): + # for customEvent in customEventsList: + # savedEvents, validationErrorMessage = attemptSaveEvent(customEvent, getFilesFromRequest(request)) + else: + try: savedEvents, validationErrorMessage = attemptSaveEvent(eventData, getFilesFromRequest(request)) - - except Exception as e: - print("Error saving event:", e) - savedEvents = False + except Exception as e: + print("Failed saving regular event", e) + # except Exception as e: + # print("Error saving event:", e) + # savedEvents = False - validationErrorMessage = "Unknown Error Saving Event. Please try again" + # validationErrorMessage = "Unknown Error Saving Event. Please try again" if savedEvents: rsvpcohorts = request.form.getlist("cohorts[]") diff --git a/app/static/js/createEvents.js b/app/static/js/createEvents.js index e0da69bf3..120e875b6 100644 --- a/app/static/js/createEvents.js +++ b/app/static/js/createEvents.js @@ -357,9 +357,9 @@ $(document).ready(function() { } }); - $(".customDate").click(function() { - $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); - }); + // $(".customDate").click(function() { + // $("#customDatePicker-" + $(this).data("page-location")).datepicker().datepicker("show"); + // }); $("#checkRSVP").click(function(){ if ($("input[name='isRsvpRequired']:checked").val() == 'on'){ @@ -411,9 +411,9 @@ $(document).ready(function() { updateDate(this) }); - $(".customDatePicker").change(function(){ //custom data calender function - updateDate(this) - }); +// $(".customDatePicker").change(function(){ //custom data calender function +// updateDate(this) +// }); $("#inputCharacters").keyup(function(event){ setCharacterLimit(this, "#remainingCharacters") diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 5f52f9e3f..1823bc069 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -419,11 +419,11 @@
-
- +
diff --git a/app/templates/base.html b/app/templates/base.html index a5e7d7fd0..72235564e 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -47,7 +47,8 @@
{% with messages = get_flashed_messages(with_categories=true) %} - + + {# #} {#FIXME: SHOULD BE THIS, WHY??#} {% endwith %}
@@ -122,7 +122,7 @@

{{page_title}}

{% endif %} + class = "startTime" id="endTime-{{pageLocation}}" data-page-location="{{pageLocation}}" required />
From c4549d75be10eb3581a4f1d205d4d86004a7e8db Mon Sep 17 00:00:00 2001 From: vungc Date: Wed, 3 Jul 2024 16:37:23 +0000 Subject: [PATCH 122/473] cleaned the debug statements in routes and modified the adminlog to display and before the last event and date so that it sounds like an actual sentence --- app/controllers/admin/routes.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 33ed61eb1..d498c7e98 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -183,23 +183,24 @@ def createEvent(templateid, programid): createAdminLog(f"Created a recurring event, {savedEvents[0].name}, for {program.programName}, with a start date of {datetime.strftime(eventData['startDate'], '%m/%d/%Y')}. The last event in the series will be on {datetime.strftime(savedEvents[-1].startDate, '%m/%d/%Y')}.") elif len(savedEventsList) >= 1 and eventData.get('isCustom'): - print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") - print("saved_event", type(savedEvents),savedEvents) - print("savedEventsList:", savedEventsList) modifiedSavedEvents = [item for sublist in savedEventsList for item in sublist] - print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") - print("modifiedSavedEvents", modifiedSavedEvents ) - event_names = [event.name for event in modifiedSavedEvents] # Extract names of all events in savedEvents + event_dates = [datetime.strptime(event_data['eventDate'], '%Y-%m-%d').date().strftime('%m/%d/%Y') for event_data in ast.literal_eval(eventData.get('customEventsData'))] - print("#############################################################################################") - print("event names:", event_names) event_list = ', '.join(f"{event.name}" for event in modifiedSavedEvents) - print("############################################################################# eventlist", event_list) - createAdminLog(f"Created {event_list} for {program.programName}, with start dates of {', '.join(event_dates)}.") + if len(modifiedSavedEvents) > 1: + #get last event name and stick at the end before 'and' so that it reads like a sentence in admin log + last_event = f"{modifiedSavedEvents[-1].name}" + event_list = ', '.join(event_list.split(', ')[:-1]) + f', and {last_event}' + #get last date and stick at the end after 'and' so that it reads like a sentence in admin log + last_event_date = event_dates[-1] + event_date_list = ', '.join(event_dates[:-1]) + f', and {last_event_date}' + + createAdminLog(f"Created events {event_list} for {program.programName}, with start dates of {event_date_list}.") + else: - createAdminLog(f"Created {savedEvents[0].name} for {program.programName}, with a start date of {datetime.strftime(eventData['startDate'], '%m/%d/%Y')}.") + createAdminLog(f"Created events {savedEvents[0].name} for {program.programName}, with a start date of {datetime.strftime(eventData['startDate'], '%m/%d/%Y')}.") else: createAdminLog(f"Created a non-program event, {savedEvents[0].name}, with a start date of {datetime.strftime(eventData['startDate'], '%m/%d/%Y')}.") From 589b6126aa7810d67d7fd8f7b6a8bd9a97a323f9 Mon Sep 17 00:00:00 2001 From: dea Date: Fri, 5 Jul 2024 08:44:57 -0400 Subject: [PATCH 123/473] Issues changed , dscssion to be had with Brian regarding future events section. --- app/templates/admin/createEvent.html | 2 +- app/templates/eventNav.html | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 22e88b3c6..14ba54b61 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -23,7 +23,7 @@ {% extends "eventNav.html"%} {% endif %} -{% set eventPast = event.isPastStart if not isNewEvent else False %} +{% set eventPast = event.isPastEnd if not isNewEvent else False %} {% set tabName = 'edit' %} diff --git a/app/templates/eventNav.html b/app/templates/eventNav.html index d408b2073..0f96f3265 100644 --- a/app/templates/eventNav.html +++ b/app/templates/eventNav.html @@ -18,17 +18,13 @@ {% if g.current_user.isAdmin %} {{ eventheader(page_title, event, 'large', isNewEvent) }} {% endif %} - indicate_Event_In_Prog - {% set isCurrentDate = current_date == event.startDate %} - {% set isCurrentTime = current_time < event.timeEnd and current_time > event.timeStart %} - {% set display = "" if eventPast or event.isCanceled or isCurrentDate or isCurrentTime else "d-none"%} + {% set display = "" if eventPast or event.isCanceled else "d-none"%} {% set alertClass = ("alert-success" if isCurrentTime else ( "alert-danger" if eventPast else "alert-warning")) %} + From 0cc1de28115b3738968e66fa4c062f8a8f605d15 Mon Sep 17 00:00:00 2001 From: vungc Date: Mon, 8 Jul 2024 17:25:02 +0000 Subject: [PATCH 125/473] flash messages appear after tojson is added back on base.html, save button on modal is now blue, and custom event IDs now exist --- app/controllers/admin/routes.py | 44 +++++++--------------------- app/logic/events.py | 10 +++++++ app/templates/admin/createEvent.html | 4 +-- app/templates/base.html | 2 +- 4 files changed, 22 insertions(+), 38 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index d498c7e98..0658aa3c3 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -32,7 +32,7 @@ from app.logic.createLogs import createAdminLog from app.logic.certification import getCertRequirements, updateCertRequirements from app.logic.utils import selectSurroundingTerms, getFilesFromRequest, getRedirectTarget, setRedirectTarget -from app.logic.events import cancelEvent, deleteEvent, attemptSaveEvent, preprocessEventData, calculateRecurringEventFrequency, deleteEventAndAllFollowing, deleteAllRecurringEvents, getBonnerEvents,addEventView, getEventRsvpCount, copyRsvpToNewEvent, getCountdownToEvent +from app.logic.events import cancelEvent, deleteEvent, attemptSaveEvent, preprocessEventData, calculateRecurringEventFrequency, deleteEventAndAllFollowing, deleteAllRecurringEvents, getBonnerEvents,addEventView, getEventRsvpCount, copyRsvpToNewEvent, getCountdownToEvent, calculateNewCustomId from app.logic.participants import getParticipationStatusForTrainings, checkUserRsvp from app.logic.minor import getMinorInterest from app.logic.fileHandler import FileHandler @@ -101,27 +101,9 @@ def createEvent(templateid, programid): # Try to save the form if request.method == "POST": eventData.update(request.form.copy()) - print(eventData.get('isCustom')) - print('################################################################################') - print(eventData) - print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$") - print(eventData.get('customEventsData')) - # print(type(eventData['customEventsData'][0])) if eventData.get('isCustom'): - customEventsList = [] - - # print(rsvp_limit) - + customEventId = calculateNewCustomId() for event in ast.literal_eval(eventData.get('customEventsData')): - print('hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh') - print(type(event['startTime'])) - print(type(event['endTime'])) - print(type(event['eventDate'])) - print(type(eventData['endDate'])) - print(eventData['rsvpLimit']) - print(type(eventData['rsvpLimit'])) - print(eventData.get("rsvpLimit") != "") - # event = dict(event) customDict = { 'program': eventData['program'], 'name': event['eventName'], @@ -139,7 +121,8 @@ def createEvent(templateid, programid): 'rsvpLimit': None if eventData.get("rsvpLimit") == "" else int(eventData.get("rsvpLimit")), 'isFoodProvided': eventData.get('isFoodProvided'), 'isService': eventData.get('isService'), - 'attachmentObject': eventData.get('attachmentObject') + 'attachmentObject': eventData.get('attachmentObject'), + 'customEventId': customEventId } try: savedEvents, validationErrorMessage = attemptSaveEvent(customDict, getFilesFromRequest(request)) @@ -147,15 +130,7 @@ def createEvent(templateid, programid): except Exception as e: print("Failed saving multi event", e) - # customEventsList.append(customDict) - - print('################################################################') - print(customDict) - - # try: - # if eventData.get('isCustom'): - # for customEvent in customEventsList: - # savedEvents, validationErrorMessage = attemptSaveEvent(customEvent, getFilesFromRequest(request)) + else: try: savedEvents, validationErrorMessage = attemptSaveEvent(eventData, getFilesFromRequest(request)) @@ -172,10 +147,11 @@ def createEvent(templateid, programid): for year in rsvpcohorts: rsvpForBonnerCohort(int(year), savedEvents[0].id) - noun = ((eventData.get('isRecurring') == 'on' or eventData.get('isCustom') == 'on') and "Events" or "Event") # pluralize + noun = ((eventData.get('isRecurring') or eventData.get('isCustom')) and "Events" or "Event") # pluralize flash(f"{noun} successfully created!", 'success') - print(type(eventData['startDate'])) + print('HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH') + print('data is:', ((eventData.get('isRecurring') or eventData.get('isCustom')) and "Events" or "Event")) if program: @@ -195,9 +171,9 @@ def createEvent(templateid, programid): event_list = ', '.join(event_list.split(', ')[:-1]) + f', and {last_event}' #get last date and stick at the end after 'and' so that it reads like a sentence in admin log last_event_date = event_dates[-1] - event_date_list = ', '.join(event_dates[:-1]) + f', and {last_event_date}' + event_dates = ', '.join(event_dates[:-1]) + f', and {last_event_date}' - createAdminLog(f"Created events {event_list} for {program.programName}, with start dates of {event_date_list}.") + createAdminLog(f"Created events {event_list} for {program.programName}, with start dates of {event_dates}.") else: createAdminLog(f"Created events {savedEvents[0].name} for {program.programName}, with a start date of {datetime.strftime(eventData['startDate'], '%m/%d/%Y')}.") diff --git a/app/logic/events.py b/app/logic/events.py index 8aa7d13d7..c01104d11 100644 --- a/app/logic/events.py +++ b/app/logic/events.py @@ -176,6 +176,7 @@ def saveEventToDb(newEventData, renewedEvent = False): eventsToCreate.append({'name': f"{newEventData['name']}", 'date':newEventData['startDate'], "week":1}) + customSeriesId = newEventData['customEventId'] else: eventsToCreate.append({'name': f"{newEventData['name']}", @@ -429,6 +430,15 @@ def calculateNewrecurringId(): return recurringId + 1 else: return 1 +def calculateNewCustomId(): + """ + Gets the highest recurring Id so that a new recurring Id can be assigned + """ + customEventId = Event.select(fn.MAX(Event.customEventId)).scalar() + if customEventId: + return customEventId + 1 + else: + return 1 def getPreviousRecurringEventData(recurringId): """ diff --git a/app/templates/admin/createEvent.html b/app/templates/admin/createEvent.html index 1823bc069..0e0d942c5 100644 --- a/app/templates/admin/createEvent.html +++ b/app/templates/admin/createEvent.html @@ -398,7 +398,6 @@