Skip to content

Commit

Permalink
Alleviate performance issues for signups (WIP)
Browse files Browse the repository at this point in the history
Also returns your new weighted hours so we can keep that updated.
  • Loading branch information
kitsuta committed Nov 8, 2024
1 parent 6b5b335 commit c25fd45
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 43 deletions.
29 changes: 16 additions & 13 deletions uber/site_sections/staffing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
from datetime import datetime, timedelta
from pockets.autolog import log
import ics
from sqlalchemy.orm import joinedload
from sqlalchemy.orm.exc import NoResultFound

from uber.config import c
from uber.custom_tags import safe_string
from uber.decorators import ajax, ajax_gettable, all_renderable, check_shutdown, csrf_protected, render, public
from uber.errors import HTTPRedirect
from uber.models import Attendee, Job
from uber.models import Attendee, Job, Shift
from uber.utils import check_csrf, create_valid_user_supplied_redirect_url, ensure_csrf_token_exists, localized_now, extract_urls


Expand Down Expand Up @@ -307,7 +308,7 @@ def get_available_jobs(self, session, all=False, highlight=False, **params):
'desc': _convert_urls(job.description),
'desc_text': job.description,
'weight': job.weight,
'slots': f"{len(job.shifts)}/{job.slots}",
'slots': f"{job.slots_taken}/{job.slots}",
'is_public': job.is_public,
'assigned': False,
}
Expand All @@ -318,15 +319,15 @@ def get_available_jobs(self, session, all=False, highlight=False, **params):
def get_assigned_jobs(self, session, **params):
volunteer = session.logged_in_volunteer()
event_list = []
jobs = session.query(Job).filter(Job.shifts.any(attendee_id=volunteer.id)).options(joinedload(Job.shifts))

for shift in volunteer.shifts:
job = shift.job
for job in jobs:
if job.is_public and job.department_id not in set(volunteer.assigned_depts_ids):
resource_id = "public_assigned"
else:
resource_id = job.department_id
event_list.append({
'id': shift.id,
'id': job.id,
'resourceIds': [resource_id],
'allDay': False,
'start': job.start_time_local.isoformat(),
Expand All @@ -338,14 +339,13 @@ def get_assigned_jobs(self, session, **params):
'desc': _convert_urls(job.description),
'desc_text': job.description,
'weight': job.weight,
'slots': f"{len(job.shifts)}/{job.slots}",
'slots': f"{job.slots_taken}/{job.slots}",
'is_public': job.is_public,
'assigned': True,
}
})
return event_list


def shifts_ical(self, session, **params):
attendee = session.logged_in_volunteer()
icalendar = ics.Calendar()
Expand Down Expand Up @@ -375,30 +375,33 @@ def jobs(self, session, all=False):
@check_shutdown
@ajax
def sign_up(self, session, job_id, **params):
message = session.assign(session.logged_in_volunteer().id, job_id)
volunteer = session.logged_in_volunteer()
message = session.assign(volunteer.id, job_id)
if message:
return {'success': False, 'message': message}
return {'success': True, 'message': "Signup complete!"}
return {'success': True, 'message': "Signup complete!", 'hours': volunteer.weighted_hours}

@check_shutdown
@ajax
def drop(self, session, shift_id, all=False):
def drop(self, session, job_id, all=False):
if c.AFTER_DROP_SHIFTS_DEADLINE:
return {
'success': False,
'message': "You can no longer drop shifts."
}
try:
shift = session.shift(shift_id)
volunteer = session.logged_in_volunteer()
shift = session.shift(job_id=job_id, attendee_id=volunteer.id)
session.delete(shift)
session.commit()
except NoResultFound:
return {
'success': True,
'message': "You've already dropped or have been unassigned from this shift."
'message': "You've already dropped or have been unassigned from this shift.",
'hours': volunteer.weighted_hours
}
finally:
return {'success': True, 'message': "Shift dropped."}
return {'success': True, 'message': "Shift dropped.", 'hours': volunteer.weighted_hours}

@public
def login(self, session, message='', first_name='', last_name='', email='', zip_code='', original_location=None):
Expand Down
80 changes: 50 additions & 30 deletions uber/templates/staffing/shifts.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h2 class="accordion-header" id="shifts-info-details-header">
<div id="shifts-info-details" class="accordion-collapse collapse show" aria-labelledby="shifts-info-details-header">
<div class="accordion-body">
<p>
You are currently signed up for {{ hours }} weighted hours worth of shifts.
You are currently signed up for <span id="weighted-hours">{{ hours }}</span> weighted hours worth of shifts.
</p>
<p>
Shifts that will overlap with your existing shifts will be hidden, and you will need to drop a shift to view them.
Expand Down Expand Up @@ -237,6 +237,9 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
if (json.success) {
$("#message-alert").addClass("alert-success").show().children('span').html(message);
shiftDetails.hide();
$("#weighted-hours").text(json.hours);
$("#weighted-hours").fadeOut(500).fadeIn(500);
fetchedEventList.length = 0;
ec.refetchEvents();
} else {
showErrorMessage(json.message);
Expand Down Expand Up @@ -266,7 +269,7 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
url: 'drop',
dataType: 'json',
data: {
shift_id: id,
job_id: id,
csrf_token: csrf_token
},
success: function (json) {
Expand All @@ -275,6 +278,7 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
if (json.success) {
$("#message-alert").addClass("alert-success").show().children('span').html(message);
shiftDetails.hide();
fetchedEventList.length = 0;
ec.refetchEvents();
} else {
showErrorMessage(json.message);
Expand Down Expand Up @@ -347,26 +351,57 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
}
}

var fetchEventsParams = {
all: '',
highlight: '',
}
var possibleEventURLS = {'available': 'get_available_jobs', 'assigned': 'get_assigned_jobs'};
var fetchEventsURLS = ['get_available_jobs', 'get_assigned_jobs'];
var fetchedEventList = new Array();
let fetchEvents = function(fetchInfo, successCallback, failureCallback) {
if (fetchedEventList.length != 0) {
successCallback(fetchedEventList);
}
for (const url of fetchEventsURLS) {
$.ajax({
method: 'GET',
url: url,
dataType: 'json',
data: fetchEventsParams,
success: function (eventList) {
fetchedEventList.push(...eventList);
},
error: function () {}
});
}

console.log(fetchedEventList);

if (fetchedEventList.length != 0) {
successCallback(fetchedEventList);
} else {
failureCallback('Unable to connect to server, please try again.');
}
}

let addEvents = function(id) {
let eventSources = ec.getOption('eventSources');
eventSources.push(possibleEventSources[id]);
ec.setOption('eventSources', eventSources);
fetchEventsURLS.push(possibleEventURLS[id]);
fetchedEventList.length = 0;
ec.refetchEvents();
toggleButton(id, 'on');
}

let removeEvents = function(id) {
let eventSources = ec.getOption('eventSources');
updatedEventSources = eventSources.filter(function(el) { return el.url != possibleEventSources[id]['url']; });
ec.setOption('eventSources', updatedEventSources);
fetchEventsURLS = fetchEventsURLS.filter(function(el) { return el != possibleEventURLS[id]; });
fetchedEventList.length = 0;
ec.refetchEvents();
toggleButton(id, 'off');
}

let setFilters = function (dropdown_name) {
let choice = $('#' + dropdown_name).val();
if (choice == "" || choice == "all") {
ec.setOption('resources', {{ default_filters|safe }})
ec.setOption('resources', {{ default_filters|safe }});
} else {
ec.setOption('resources', []);
addFilter(choice);
Expand All @@ -388,14 +423,13 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
}

let setFetchParams = function (paramChanges) {
currentParams = possibleEventSources['available']['extraParams'];
for (const [key, value] of Object.entries(paramChanges)) {
possibleEventSources['available']['extraParams'][key] = value;
fetchEventsParams[key] = value;
}
let eventSources = ec.getOption('eventSources');
if (eventSources.filter(function(el) { return el.url == possibleEventSources['available']['url']; })) {
removeEvents('available');
addEvents('available');

if ('get_available_jobs' in fetchEventsURLS) {
fetchedEventList.length = 0;
ec.refetchEvents();
}
}

Expand Down Expand Up @@ -511,20 +545,6 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
}

const allFilters = {{ all_filters|safe }}
let possibleEventSources = {
'available': {
url: 'get_available_jobs',
method: 'GET',
extraParams: {
'all': '',
'highlight': '',
}
},
'assigned': {
url: 'get_assigned_jobs',
method: 'GET',
}
}

const ec = new EventCalendar(document.getElementById('shift_cal'), {
view: window.matchMedia('(max-width: 576px)').matches ? 'listWeek' : 'timeGridWeek',
Expand Down Expand Up @@ -571,7 +591,7 @@ <h2 class="accordion-header" id="restricted-jobs-info-header">
}
},
viewDidMount: showOtherView,
eventSources: [possibleEventSources['available'], possibleEventSources['assigned']],
eventSources: [{events: fetchEvents}],
eventContent: renderEvent,
eventClick: showEventDetails,
filterEventsWithResources: true,
Expand Down

0 comments on commit c25fd45

Please sign in to comment.