Skip to content
This repository was archived by the owner on Sep 7, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
File renamed without changes.
29 changes: 29 additions & 0 deletions migrations/versions/046d24dc80b6_require_appointment_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""require appointment fields

Revision ID: 046d24dc80b6
Revises: 4c81c3744bc4
Create Date: 2020-08-01 04:40:56.908992

"""

# revision identifiers, used by Alembic.
revision = '046d24dc80b6'
down_revision = '4c81c3744bc4'

from alembic import op
import sqlalchemy as sa
import oh_queue.models
from oh_queue.models import *


def upgrade():
connection = op.get_bind()
session = orm.Session(bind=connection)

for course in session.query(ConfigEntry.course).distinct():
session.add(ConfigEntry(key='appointment_fields_required', value='false', public=True, course=course[0]))

session.commit()

def downgrade():
pass
2 changes: 2 additions & 0 deletions migrations/versions/ee50ab5f3371_added_appointments_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

from alembic import op
import sqlalchemy as sa
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
import oh_queue.models
from oh_queue.models import *

Expand Down
16 changes: 15 additions & 1 deletion oh_queue/static/js/components/admin_appointments_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ function AdminAppointmentsManager({ state }) {
/>
</td>
</tr>
<tr>
<td>Should all fields be required for new appointments?</td>
<td className="col-md-1">
<ConfigLinkedToggle
config={state.config}
configKey="appointment_fields_required"
offText="No"
onText="Yes"
/>
</td>
</tr>
<tr>
<td>
<p>
Expand Down Expand Up @@ -61,8 +72,11 @@ function AdminAppointmentsManager({ state }) {
<tr>
<td>
<p>
How many appointments should a student have be pending simultaneously?
How many appointments should a student have be pending simultaneously?
</p>
(by
<ConfigLinkedToggle config={state.config} configKey="appointment_or_minutes" onText="minutes" offText="number"/>
)
</td>
<td className="col-md-3">
<ConfigLinkedNumeric
Expand Down
1 change: 1 addition & 0 deletions oh_queue/static/js/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class App extends React.Component {
"slack_notif_appt_summary",
"slack_notif_missed_appt",
"party_enabled",
"appointment_fields_required"
]) {
this.state.config[key] = JSON.parse(this.state.config[key]);
}
Expand Down
26 changes: 15 additions & 11 deletions oh_queue/static/js/components/appointment_overlay.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function AppointmentOverlay({ staffMode, appointment, assignments, signup, onSubmit, isOpen }) {
function AppointmentOverlay({ staffMode, appointment, assignments, signup, onSubmit, isOpen, state }) {
const [email, setEmail] = React.useState("");
const [assignment, setAssignment] = React.useState("");
const [question, setQuestion] = React.useState("");
Expand Down Expand Up @@ -38,15 +38,19 @@ function AppointmentOverlay({ staffMode, appointment, assignments, signup, onSub
};

const handleSubmit = () => {
app.makeRequest(
'assign_appointment', {
appointment_id: appointment,
assignment_id: parseInt(assignment),
question: question,
description: description,
email: signup ? signup.user.email : email,
});
onSubmit();
if (state.config.appointment_fields_required && assignment && question && description) {
app.makeRequest(
'assign_appointment', {
appointment_id: appointment,
assignment_id: parseInt(assignment),
question: question,
description: description,
email: signup ? signup.user.email : email,
});
onSubmit();
} else {
alert("Please fill out all fields.")
}
};

return ReactDOM.createPortal(
Expand All @@ -64,7 +68,7 @@ function AppointmentOverlay({ staffMode, appointment, assignments, signup, onSub
<div className="modal-body">
{!staffMode && (
<p>
Leave fields blank if you aren't yet sure what you want to ask about.
Please fill out all fields to the best of your ability. You can always come back and edit them later.
</p>
)}
<SlotsForm
Expand Down
3 changes: 2 additions & 1 deletion oh_queue/static/js/components/confirmed_appointment_card.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function ConfirmedAppointmentCard({ appointment, signup, locations, assignments }) {
function ConfirmedAppointmentCard({ appointment, signup, locations, assignments , state}) {
const assignmentName = signup.assignment_id && assignments[signup.assignment_id].name;
const questionName = signup.question ? " Question " + signup.question : "";

Expand Down Expand Up @@ -53,6 +53,7 @@ function ConfirmedAppointmentCard({ appointment, signup, locations, assignments
signup={signup}
isOpen={modalOpen}
onSubmit={() => setModalOpen(false)}
state={state}
/>
</React.Fragment>
)
Expand Down
1 change: 1 addition & 0 deletions oh_queue/static/js/components/future_slots.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ function FutureSlots({ state }) {
staffMode={currentUser && currentUser.isStaff}
isOpen={modalOpen}
onSubmit={handleSubmit}
state={state}
/>
</React.Fragment>
);
Expand Down
1 change: 1 addition & 0 deletions oh_queue/static/js/components/my_appointments.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function MyAppointments({ state }) {
appointment={appointment}
signup={signup}
onClick={handleClick}
state={state}
/>
)
});
Expand Down
29 changes: 25 additions & 4 deletions oh_queue/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ def init_config():
public=True,
course=get_course(),
))
db.session.add(ConfigEntry(
key='appointment_or_minutes',
value='false',
public=True,
course=get_course(),
))
db.session.add(ConfigEntry(
key='show_okpy_backups',
value='false',
Expand Down Expand Up @@ -349,6 +355,12 @@ def init_config():
public=True,
course=get_course(),
))
db.session.add(ConfigEntry(
key='appointment_fields_required',
value='false',
public=True,
course=get_course(),
))
db.session.commit()

# We run a React app, so serve index.html on all routes
Expand Down Expand Up @@ -922,6 +934,7 @@ def assign_appointment(data):
daily_threshold = int(ConfigEntry.query.filter_by(key="daily_appointment_limit", course=get_course()).one().value)
weekly_threshold = int(ConfigEntry.query.filter_by(key="weekly_appointment_limit", course=get_course()).one().value)
pending_threshold = int(ConfigEntry.query.filter_by(key="simul_appointment_limit", course=get_course()).one().value)
pending_metric= ConfigEntry.query.filter_by(key="appointment_or_minutes", course=get_course()).one().value

start = appointment.start_time.replace(hour=0, minute=0, second=0, microsecond=0)
week_start = start - datetime.timedelta(days=appointment.start_time.weekday())
Expand All @@ -940,13 +953,21 @@ def assign_appointment(data):
).count()
if num_today >= daily_threshold:
return socket_error("You have already signed up for {} OH slots for the same day".format(daily_threshold))

num_pending = AppointmentSignup.query.join(AppointmentSignup.appointment).filter(
Appointment.status == AppointmentStatus.pending,
AppointmentSignup.user_id == current_user.id,
).count()
if num_pending >= pending_threshold:
return socket_error("You have already signed up for {} OH slots that have not yet occurred.".format(pending_threshold))
)
if pending_metric != 'false':
start = appointment.duration
num_pend = [appt.appointment.duration for appt in list(num_pending)]
threshold = datetime.timedelta(minutes=pending_threshold)
for item in num_pend:
start += item
if start > threshold:
return socket_error("You cannot sign up for more than {} minutes of OH that have not yet occurred.".format(pending_threshold))
else:
if num_pending.count() >= pending_threshold:
return socket_error("You have already signed up for {} OH slots that have not yet occurred.".format(pending_threshold))

old_signup = AppointmentSignup.query.filter_by(
appointment_id=data["appointment_id"],
Expand Down