Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Refactor Program Management section of Admin Settings #1281

Open
wants to merge 55 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
f850ec3
New Branch with changes from previous. Image
JohnCox2211 Jul 5, 2024
d5fe95d
changed coverImage to be a blobfield. cleaned up
JohnCox2211 Jul 5, 2024
ebf80d2
More attempts for file handling, trying to modify
JohnCox2211 Jul 8, 2024
0053012
Deleted partner.py because it was not being used
JohnCox2211 Jul 8, 2024
874a913
added some notes about what returns are for
JohnCox2211 Jul 9, 2024
d1f035a
modified the modal so we could store the images of the filepaths
Kafui123 Jul 10, 2024
230ee45
modified image storing to database
Kafui123 Jul 10, 2024
decdb3d
we are on to something
Kafui123 Jul 10, 2024
19c1b2c
Fixed Issuegit status !
Kafui123 Jul 11, 2024
be36260
Picture appeared, at some point of time, but it disappeared again. Cu…
Jul 11, 2024
a7eb026
changes we have made so far
Kafui123 Jul 12, 2024
e40eb96
Issue fixed, the modal works, the delete button does not close the mo…
Jul 15, 2024
19040fd
updated code that reflects all the changes that work
Kafui123 Jul 16, 2024
4702612
Merge branch 'development' into refactorProgramMgmt
AravDe Jul 17, 2024
f8a6a2a
modified changes
Kafui123 Jul 17, 2024
14b3eca
updates
Kafui123 Jul 17, 2024
4089296
Test suites almost fixed. Working on Mocking Filestorage object for t…
Jul 17, 2024
7f27709
updated code yet
Kafui123 Jul 19, 2024
abc75f0
Added scroll feature to modal but now planning on removing again. Tes…
Jul 22, 2024
7f472f9
modified changes
Kafui123 Jul 22, 2024
7067204
modified code
Kafui123 Jul 22, 2024
ddcae6f
Handing over to Kafui
Jul 22, 2024
f1280c6
modified changes
Kafui123 Jul 22, 2024
8545c4e
changes
Kafui123 Jul 22, 2024
52d56ab
Changes to Kafui
esw0624 Jul 22, 2024
04c7f87
modified changes
Kafui123 Jul 22, 2024
4a663bd
modified changes
Kafui123 Jul 22, 2024
16407d5
updates for pr
Kafui123 Jul 22, 2024
0399f4b
Merge branch 'development' into refactorProgramMgmt
Kafui123 Jul 22, 2024
3f99551
Update for my local branch
esw0624 Jul 23, 2024
7f219b5
final code ready for review
Kafui123 Jul 23, 2024
d631b1f
final code changes
Kafui123 Jul 23, 2024
2aaf254
Merge branch 'development' into refactorProgramMgmt
Kafui123 Jul 23, 2024
bfe21fe
Update
esw0624 Jul 24, 2024
2aaf332
Update for branch
esw0624 Jul 25, 2024
6a7af85
userpr
Kafui123 Jul 24, 2024
91d55b6
modified changes
Kafui123 Jul 24, 2024
a1ca894
checking to see if my commits are being sent to the remote bramch
Kafui123 Jul 24, 2024
cdbc950
this commit reflects all updated changes that my partner, eun can pul…
Kafui123 Jul 25, 2024
e1ff16b
necessary merge to get in sync with my remotebranch
Kafui123 Jul 25, 2024
38fbf19
final code changes for July 25
Kafui123 Jul 25, 2024
9831544
commit for friday july -26 (most recent code update)
Kafui123 Jul 26, 2024
f4a42d6
Merge branch 'development' into refactorProgramMgmt
esw0624 Jul 26, 2024
dca0ec5
most recent code on july 29th
Kafui123 Jul 29, 2024
5ce9768
most recent code for july 30th
Kafui123 Jul 30, 2024
bd5bed9
most recent code change for july 30th
Kafui123 Jul 30, 2024
adc1087
final code ready for pr review july 31st
Kafui123 Jul 31, 2024
57fee5b
Merge branch 'development' into refactorProgramMgmt
BrianRamsay Jul 31, 2024
b58673b
final code changes for July 31st
Kafui123 Jul 31, 2024
f092bba
final code updates for July 31st
Kafui123 Jul 31, 2024
57da6e1
merge necessary to update my local branch to my remote branch
Kafui123 Jul 31, 2024
7d7fb9a
most recent code update for august 2nd
Kafui123 Aug 2, 2024
002d470
Merge branch 'development' into refactorProgramMgmt
bledsoef Aug 22, 2024
eea8a51
Switch the landingPage image names to program IDs
WackyWeaver Sep 4, 2024
fd01a4b
Merge branch 'refactorProgramMgmt' of https://github.com/BCStudentSof…
WackyWeaver Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ ldap:

files:
base_path: 'app/static/files'
image_path: 'app/static/images'
landing_page_path: 'landingPage'
email_attachment_path: 'emailattachments'
event_attachment_path: 'eventattachments'
course_attachment_path: 'courseattachments'
program_image_path: 'programimages'
esw0624 marked this conversation as resolved.
Show resolved Hide resolved

MAIL_ENABLED: True
MAIL_SERVER: "smtp.gmail.com" # use smtp.gmail.com for gmail, mail.berea.edu for Berea
Expand Down
35 changes: 23 additions & 12 deletions app/controllers/admin/userManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
from app.models.program import Program
from app.logic.userManagement import addCeltsAdmin,addCeltsStudentStaff,removeCeltsAdmin,removeCeltsStudentStaff
from app.logic.userManagement import changeProgramInfo
from app.logic.utils import selectSurroundingTerms
from app.logic.utils import selectSurroundingTerms, getFilesFromRequest
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 @@ -52,7 +55,7 @@ def manageUsers():
def addProgramManagers():
eventData = request.form
try:
return addProgramManager(eventData['username'],int(eventData['programID']))
return addProgramManagers(eventData['username'],int(eventData['programID']))
except Exception as e:
print(e)
flash('Error while trying to add a manager.','warning')
Expand All @@ -62,29 +65,37 @@ def addProgramManagers():
def removeProgramManagers():
eventData = request.form
try:
return removeProgramManager(eventData['username'],int(eventData['programID']))
return removeProgramManagers(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.")
esw0624 marked this conversation as resolved.
Show resolved Hide resolved

@admin_bp.route('/deleteProgramFile', methods=['POST'])
def deleteProgramFile():
fileData= request.form
esw0624 marked this conversation as resolved.
Show resolved Hide resolved
programFile=FileHandler(programId=fileData["databaseId"])
esw0624 marked this conversation as resolved.
Show resolved Hide resolved
programFile.deleteFile(fileData["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)

associatedAttachments = list(AttachmentUpload.select().where(AttachmentUpload.program == programID).execute())

filePaths = FileHandler(programId=programID).retrievePath(associatedAttachments)

file_paths = {filename: path_info[0] for filename, path_info in filePaths.items()}
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')
print("error: ", e)
flash('Error while updating program info.','warning')
abort(500,'Error while updating program.')
abort(403)

Expand Down
40 changes: 35 additions & 5 deletions app/logic/fileHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@
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
def __init__(self, files=None, courseId=None, eventId=None, programId=None):
self.files = files
self.path = app.config['files']['base_path']
self.image_path = app.config['files']['image_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.image_path = os.path.join(self.image_path, app.config['files']['landing_page_path'])
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
def makeDirectory(self):
try:
extraDir = str(self.eventId) if self.eventId else ""
Expand All @@ -25,17 +30,25 @@ def makeDirectory(self):

def getFileFullPath(self, newfilename=''):
try:
filePath = (os.path.join(self.path, newfilename))
if self.eventId or self.courseId:
filePath = (os.path.join(self.path, newfilename))
elif self.programId:
filePath = (os.path.join(self.image_path, newfilename))
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
except AttributeError:
pass
except FileExistsError:
pass
return filePath

def saveFiles(self, saveOriginalFile=None):
try:

try:
if not isinstance(self.files, list):
self.files = [self.files]
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
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 +62,28 @@ def saveFiles(self, saveOriginalFile=None):
if not isFileInCourse:
AttachmentUpload.create(course=self.courseId, fileName=file.filename)
saveFileToFilesystem = file.filename
elif self.programId:
isFileInProgram = AttachmentUpload.select().where(AttachmentUpload.program == self.programId, AttachmentUpload.fileName == file.filename).exists()
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
if not isFileInProgram:
AttachmentUpload.create(program=self.programId, fileName=file.filename)
name = Program.get(Program.id == self.programId)
file_type = file.filename.split('.')[1]
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
current_programName = f"{str(name.programName)}.{file_type}"
pattern = '*' + str(name.programName) + '*'
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved

full_pattern = os.path.join(self.image_path, pattern)
files_to_delete = glob.glob(full_pattern)


Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
for file_path in files_to_delete:
os.remove(file_path)
saveFileToFilesystem = current_programName
else:
saveFileToFilesystem = file.filename
if saveFileToFilesystem:
self.makeDirectory()
file.save(self.getFileFullPath(newfilename=saveFileToFilesystem))

except AttributeError:
pass

Expand Down
52 changes: 39 additions & 13 deletions app/logic/userManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
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 +39,45 @@ 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(newProgramName, newContactEmail, newContactName, newLocation, programId):
"""Updates the program info with a new sender and email."""
def changeProgramInfo(programId, attachment, programName= None, programDescription = None, partner = None, contactEmail=None, contactName= None, location = None,instagramUrl = None, facebookUrl = None, bereaUrl = None):
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved


"""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)
coverImage = program.coverImage
if attachment:
print(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.coverImage: attachment,
Program.instagramUrl:instagramUrl,
Program.facebookUrl: facebookUrl,
Program.bereaUrl: bereaUrl
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
}
).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 +95,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.

4 changes: 2 additions & 2 deletions app/models/program.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
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)
contactName = CharField(null=True,default='')
contactEmail = CharField(null=True,default='')
defaultLocation = CharField(null=True,default='')
coverImage = BlobField(null=True)
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved

@property
def url(self):
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
57 changes: 57 additions & 0 deletions app/static/css/programManagement.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.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 */
}

@media (max-width: 1500px) {
.btn {
height: 60px;
}
.step {
width: 13px;
height: 13px;
}
}

@media (max-width: 1100px) {
.btn {
height: 80px;
}
.step {
width: 10px;
height: 10px;
}
}
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions app/static/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ function handleFileSelection(fileInputId){
$(fullTrashId).data("file", file);
$(fullTrashId).data("file-container-id", attachedObjectContainerId);
$(fullTrashId).on("click", function() {
console.log("hehe")
Kafui123 marked this conversation as resolved.
Show resolved Hide resolved
let elementFileNum = $(this).data('filenum');
let attachedObjectContainerId = $(this).data('file-container-id');
$("#"+ attachedObjectContainerId + " #attachedFilesRow" + elementFileNum).remove();
Expand Down
Loading
Loading