Skip to content

Commit

Permalink
Merge pull request #1281 from BCStudentSoftwareDevTeam/refactorProgra…
Browse files Browse the repository at this point in the history
…mMgmt

Refactor Program Management section of Admin Settings
  • Loading branch information
WackyWeaver authored Dec 2, 2024
2 parents eaae371 + 6554990 commit 90449ed
Show file tree
Hide file tree
Showing 29 changed files with 433 additions and 125 deletions.
2 changes: 2 additions & 0 deletions app/config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ ldap:

files:
base_path: 'app/static/files'
image_path: 'app/static/images'
program_attachment_path: 'programattachments'
email_attachment_path: 'emailattachments'
event_attachment_path: 'eventattachments'
course_attachment_path: 'courseattachments'
Expand Down
38 changes: 11 additions & 27 deletions app/controllers/admin/userManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from app.logic.userManagement import changeProgramInfo
from app.logic.utils import selectSurroundingTerms
from app.logic.term import addNextTerm, changeCurrentTerm
from app.logic.fileHandler import FileHandler
from app.models.attachmentUpload import AttachmentUpload

@admin_bp.route('/admin/manageUsers', methods = ['POST'])
def manageUsers():
Expand Down Expand Up @@ -48,43 +50,25 @@ def manageUsers():
flash(user.firstName + " " + user.lastName + " is no longer a CELTS Student Staff", 'success')
return ("success")

@admin_bp.route('/addProgramManagers', methods=['POST'])
def addProgramManagers():
eventData = request.form
try:
return addProgramManager(eventData['username'],int(eventData['programID']))
except Exception as e:
print(e)
flash('Error while trying to add a manager.','warning')
abort(500,"'Error while trying to add a manager.'")

@admin_bp.route('/removeProgramManagers', methods=['POST'])
def removeProgramManagers():
eventData = request.form
try:
return removeProgramManager(eventData['username'],int(eventData['programID']))
except Exception as e:
print(e)
flash('Error while removing a manager.','warning')
abort(500,"Error while trying to remove a manager.")
@admin_bp.route('/deleteProgramFile', methods=['POST'])
def deleteProgramFile():
programFile=FileHandler(programId=request.form["programID"])
programFile.deleteFile(request.form["fileId"])
return ""

@admin_bp.route('/admin/updateProgramInfo/<programID>', methods=['POST'])
def updateProgramInfo(programID):
"""Grabs info and then outputs it to logic function"""
programInfo = request.form # grabs user inputs
if g.current_user.isCeltsAdmin:
try:
changeProgramInfo(programInfo["programName"], #calls logic function to add data to database
programInfo["contactEmail"],
programInfo["contactName"],
programInfo["location"],
programID)
programInfo = request.form # grabs user inputs
uploadedFile = request.files.get('modalProgramImage')
changeProgramInfo(programID, uploadedFile, **programInfo)

flash("Program updated", "success")
return redirect(url_for("admin.userManagement", accordion="program"))
except Exception as e:
print(e)
flash('Error while updating program info.','warning')
flash('Error while updating program info.','warning')
abort(500,'Error while updating program.')
abort(403)

Expand Down
37 changes: 31 additions & 6 deletions app/logic/fileHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@
from flask import redirect, url_for
from app import app
from app.models.attachmentUpload import AttachmentUpload
from app.models.program import Program
import glob

class FileHandler:
def __init__(self, files=None, courseId=None, eventId=None):
self.files = files
self.path = app.config['files']['base_path']
def __init__(self, files=None, courseId=None, eventId=None, programId=None):
self.files = files
if not isinstance(self.files, list):
self.files = [self.files]
self.path = app.config['files']['base_path']
self.courseId = courseId
self.eventId = eventId
self.programId = programId
if courseId:
self.path = os.path.join(self.path, app.config['files']['course_attachment_path'], str(courseId))
elif eventId:
self.path = os.path.join(self.path, app.config['files']['event_attachment_path'])

elif programId:
self.path = os.path.join(self.path, app.config['files']['program_attachment_path'])

def makeDirectory(self):
try:
extraDir = str(self.eventId) if self.eventId else ""
Expand All @@ -25,17 +32,19 @@ def makeDirectory(self):

def getFileFullPath(self, newfilename=''):
try:
filePath = (os.path.join(self.path, newfilename))
if self.eventId or self.courseId or self.programId:
filePath = (os.path.join(self.path, newfilename))
except AttributeError:
pass
except FileExistsError:
pass
return filePath

def saveFiles(self, saveOriginalFile=None):
try:
try:
for file in self.files:
saveFileToFilesystem = None

if self.eventId:
attachmentName = str(saveOriginalFile.id) + "/" + file.filename
isFileInEvent = AttachmentUpload.select().where(AttachmentUpload.event_id == self.eventId,
Expand All @@ -49,11 +58,27 @@ def saveFiles(self, saveOriginalFile=None):
if not isFileInCourse:
AttachmentUpload.create(course=self.courseId, fileName=file.filename)
saveFileToFilesystem = file.filename
elif self.programId:

# remove the existing file
deleteFileObject = AttachmentUpload.get_or_none(program=self.programId)
if deleteFileObject:
self.deleteFile(deleteFileObject.id)

# add the new file
fileType = file.filename.split('.')[-1]
fileName = f"{self.programId}.{fileType}"
AttachmentUpload.create(program=self.programId, fileName=fileName)
currentProgramID = fileName
saveFileToFilesystem = currentProgramID

else:
saveFileToFilesystem = file.filename

if saveFileToFilesystem:
self.makeDirectory()
file.save(self.getFileFullPath(newfilename=saveFileToFilesystem))

except AttributeError:
pass

Expand Down
6 changes: 3 additions & 3 deletions app/logic/landingPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ def getManagerProgramDict(user):

for program in programs:
managerProgramDict[program] = {"managers": "", "image": os.path.join('static', 'images/logos/celts_symbol.png')}
with os.scandir("./app/static/images/landingPage") as it:
with os.scandir("./app/static/files/programattachments") as it:
for entry in it:
if entry.name.split('.')[0] == f'{program.programName}':
managerProgramDict[program]["image"] = os.path.join('static', f'images/landingPage/{entry.name}')
if entry.name.split('.')[0] == f'{program.id}':
managerProgramDict[program]["image"] = os.path.join('static', f'files/programattachments/{entry.name}')
break
for row in managerRows:
if managerProgramDict[row.program]["managers"] == "":
Expand Down
58 changes: 46 additions & 12 deletions app/logic/userManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
from app.models.programManager import ProgramManager
from app.models.program import Program
from app.models.eventTemplate import EventTemplate
from app.models.attachmentUpload import AttachmentUpload
from flask import g, session
from app.logic.createLogs import createActivityLog
from playhouse.shortcuts import model_to_dict
from app.logic.fileHandler import FileHandler

def addCeltsAdmin(user):
user = User.get_by_id(user)
Expand Down Expand Up @@ -38,20 +40,52 @@ def removeCeltsStudentStaff(user):
createActivityLog(f'Removed {user.firstName} {user.lastName} from a CELTS student staff member'+
(f', and as a manager of {programManagerRoles}.' if programManagerRoles else "."))

def changeProgramInfo(programId,
attachment,
programName= None,
programDescription = None,
partner = None,
contactEmail=None,
contactName= None,
location = None,
instagramUrl = None,
facebookUrl = None,
bereaUrl = None):


def changeProgramInfo(newProgramName, newContactEmail, newContactName, newLocation, programId):
"""Updates the program info with a new sender and email."""
"""Updates the program info and logs that change"""
program = Program.get_by_id(programId)
updatedProgram = Program.update({Program.programName:newProgramName, Program.contactEmail: newContactEmail, Program.contactName:newContactName, Program.defaultLocation:newLocation}).where(Program.id==programId)
if attachment:
addFile: FileHandler = FileHandler(attachment, programId=programId)
addFile.saveFiles()
updatedProgram = Program.update(
{ Program.programName:programName,
Program.programDescription: programDescription,
Program.partner: partner,
Program.contactEmail: contactEmail,
Program.contactName: contactName,
Program.defaultLocation: location,
Program.instagramUrl:instagramUrl,
Program.facebookUrl: facebookUrl,
Program.bereaUrl: bereaUrl
}
).where(Program.id==programId)
updatedProgram.execute()
if newProgramName != program.programName:
createActivityLog(f"{program.programName} Program Name was changed to: {newProgramName}")
if newContactEmail != program.contactEmail:
createActivityLog(f"{program.programName} Contact Email was changed to: {newContactEmail}")
if newContactName != program.contactName:
createActivityLog(f"{program.programName} Contact Name was changed to: {newContactName}")
if newLocation != program.defaultLocation:
createActivityLog(f"{program.programName} Location was changed to: {newLocation}")


if programName != program.programName:
createActivityLog(f"{program.programName} Program Name was changed to: {programName}")
if programDescription != program.programDescription:
createActivityLog(f"{program.programName} Description was changed to: {programDescription}")
if partner != program.partner:
createActivityLog(f"{program.programName} Program Partner was changed to: {partner}")
if contactEmail != program.contactEmail:
createActivityLog(f"{program.programName} Contact Email was changed to: {contactEmail}")
if contactName != program.contactName:
createActivityLog(f"{program.programName} Contact Name was changed to: {contactName}")
if location != program.defaultLocation:
createActivityLog(f"{program.programName} Location was changed to: {location}")


return (f'Program email info updated')

Expand All @@ -69,4 +103,4 @@ def getAllowedTemplates(currentUser):
if currentUser.isCeltsAdmin:
return EventTemplate.select().where(EventTemplate.isVisible==True).order_by(EventTemplate.name)
else:
return []
return []
2 changes: 2 additions & 0 deletions app/models/attachmentUpload.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from app.models import*
from app.models.event import Event
from app.models.course import Course
from app.models.program import Program
from app.models.otherExperience import OtherExperience


class AttachmentUpload(baseModel):
event = ForeignKeyField(Event, null=True)
course = ForeignKeyField(Course, null=True)
program = ForeignKeyField(Program, null=True)
isDisplayed = BooleanField(default=False)
fileName = CharField()

4 changes: 0 additions & 4 deletions app/models/partner.py

This file was deleted.

3 changes: 1 addition & 2 deletions app/models/program.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
from app.models import*
from app.models.term import Term
from app.models.courseStatus import CourseStatus
from app.models.partner import Partner

class Program(baseModel):
programName = CharField()
instagramUrl = TextField(null=True)
facebookUrl = TextField(null=True)
bereaUrl = TextField(null=True)
programDescription = TextField()
partner = ForeignKeyField(Partner, null=True)
partner = CharField(null=True)
isStudentLed = BooleanField(default=False)
isBonnerScholars = BooleanField(default=False)
isOtherCeltsSponsored = BooleanField(default=False)
Expand Down
2 changes: 1 addition & 1 deletion app/static/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

.toast-container{
top: 0;
z-index: 11;
z-index: 1060;
}

.form-control.invalid,
Expand Down
38 changes: 38 additions & 0 deletions app/static/css/programManagement.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.modal {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
/* Removed incorrect translate */
}

.modal-dialog-scrollable {
max-height: calc(100vh - 200px);
overflow-y: auto;
}


.info {
overflow-y: auto;
margin-top: -20px;
}

.cellSpacing {
margin: 5px;
padding: 10px;
}

.programHeader {
border-bottom: 1px solid black;
font-weight: bold;
}

.borderless {
border: 0;
}

.rightJustify {
position: absolute;
right: 10px; /* Added px to right */
}

Binary file added app/static/files/programattachments/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/files/programattachments/10.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Binary file added app/static/files/programattachments/4.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/files/programattachments/5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/files/programattachments/6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/files/programattachments/7.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/files/programattachments/8.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 23 additions & 12 deletions app/static/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function getSelectedFiles(){
return _fileHolder.files;
}

function handleFileSelection(fileInputId){
function handleFileSelection(fileInputId, single=false){
var fileBoxId = "#" + fileInputId
var attachedObjectContainerId = fileInputId + "Container"
$(fileBoxId).after(`<div id="`+attachedObjectContainerId+`" class="py-0 px-0"></div>`)
Expand Down Expand Up @@ -191,16 +191,22 @@ function handleFileSelection(fileInputId){
}
let trashNum = ($(objectContainerId+ " .row").length)
var fullTrashId = "#trash" + trashNum
$(objectContainerId).append(" \
<div class='border row p-0 m-0' id='attachedFilesRow" +trashNum+"'> \
<i class='col-auto fs-3 px-3 bi " + iconClass + "'></i> \
<div id='attachedFile" + trashNum + "' data-filename='" + file.name + "' class='fileName col-auto pt-2'>" + fileName + "</div> \
<div class='col' style='text-align:right'> \
<div class='btn btn-danger fileHolder p-1 my-1 mx-1' id='trash" + trashNum + "' data-filenum='" + trashNum + "'>\
<span class='bi bi-trash fs-6'></span>\
</div>\
</div> \
</div>")
let fileHTML = " \
<div class='border row p-0 m-0' id='attachedFilesRow" +trashNum+"'> \
<i class='col-auto fs-3 px-3 bi " + iconClass + "'></i> \
<div id='attachedFile" + trashNum + "' data-filename='" + file.name + "' class='fileName col-auto pt-2'>" + fileName + "</div> \
<div class='col' style='text-align:right'> \
<div class='btn btn-danger fileHolder p-1 my-1 mx-1' id='trash" + trashNum + "' data-filenum='" + trashNum + "'>\
<span class='bi bi-trash fs-6'></span>\
</div>\
</div> \
</div>"
if (single) {
$(objectContainerId).html(fileHTML)
}
else {
$(objectContainerId).append(fileHTML)
}
$(fullTrashId).data("file", file);
$(fullTrashId).data("file-container-id", attachedObjectContainerId);
$(fullTrashId).on("click", function() {
Expand All @@ -212,7 +218,12 @@ function handleFileSelection(fileInputId){
$(fileBoxId).data("file-num", $(fileBoxId).data("file-num") + 1)
}
else{
msgToast("File with filename '" + file.name + "' has already been added to this event")
if (single){
$(objectContainerId).html(fileHTML)
}
else{
msgToast("File with filename '" + file.name + "' has already been added to this event")
}
}
}
$(fileBoxId).prop('files', getSelectedFiles());
Expand Down
3 changes: 2 additions & 1 deletion app/static/js/displayFilesMacro.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
$(document).ready(function(){
$("a.fileName").tooltip();

$(".removeAttachment").on("click", function(){
$(".removeAttachment").on("click", function(e){
e.preventDefault();
let fileId = $(this).data("id");
let deleteLink = $(this).data("delete-url");
let fileData = {
Expand Down
Loading

0 comments on commit 90449ed

Please sign in to comment.