diff --git a/oh_queue/static/css/style.css b/oh_queue/static/css/style.css
index cbe5276..14d725c 100644
--- a/oh_queue/static/css/style.css
+++ b/oh_queue/static/css/style.css
@@ -749,6 +749,18 @@ h1.truncate, h2.truncate, h3.truncate, h4.truncate, h5.truncate, h6.truncate {
border-color: orange;
}
+.panel-warning-short > .panel-heading {
+ color: #fff;
+ background: repeating-linear-gradient(
+ 45deg,
+ orange,
+ orange 10px,
+ #EE9E00 10px,
+ #EE9E00 20px
+ );
+ border-color: #EE9E00;
+}
+
.panel-success {
border-color: #4cae4c;
}
@@ -759,6 +771,41 @@ h1.truncate, h2.truncate, h3.truncate, h4.truncate, h5.truncate, h6.truncate {
border-color: #4cae4c;
}
+.panel-success-short > .panel-heading {
+ color: #fff;
+ background: repeating-linear-gradient(
+ 45deg,
+ #5cb85c,
+ #5cb85c 10px,
+ #4cae4c 10px,
+ #4cae4c 20px
+ );
+ border-color: #4cae4c;
+}
+
+.panel-primary-short > .panel-heading {
+ color: #fff;
+ background: repeating-linear-gradient(
+ 45deg,
+ #337ab7,
+ #337ab7 10px,
+ #3C8CD1 10px,
+ #3C8CD1 20px
+ );
+ border-color: #337ab7;
+}
+
+.panel-danger-short > .panel-heading {
+ color: #ac4b49;
+ background: repeating-linear-gradient(
+ 45deg,
+ #f2dede,
+ #f2dede 10px,
+ #F5D0D0 10px,
+ #F5D0D0 20px
+ );
+ border-color: #F5D0D0;
+}
.btn-take-over {
position: absolute;
@@ -839,6 +886,21 @@ h4.list-group-item-heading::before {
border-top: 1px solid #ddd;;
}
+.panel.panel-default-short > .panel-heading{
+ border-top: 1px solid #ddd;
+ background: repeating-linear-gradient(
+ 45deg,
+ #ddd,
+ #ddd 10px,
+ #D0D0D0 10px,
+ #D0D0D0 20px
+ );
+}
+
+.panel.panel-default {
+ border-top: 1px solid #ddd;;
+}
+
.tooltip+.btn-block {
margin-top: 5px;
}
diff --git a/oh_queue/static/js/components/admin_appointments_manager.js b/oh_queue/static/js/components/admin_appointments_manager.js
index cd3001f..382cc3b 100644
--- a/oh_queue/static/js/components/admin_appointments_manager.js
+++ b/oh_queue/static/js/components/admin_appointments_manager.js
@@ -61,8 +61,11 @@ function AdminAppointmentsManager({ state }) {
- How many appointments should a student have be pending simultaneously?
+ How many appointments should a student have be pending simultaneously?
+ (by
+
+ )
|
Math.max(0, appointment.capacity - appo
function AppointmentCard({ currentUser, locations, appointment, assignments, compact, onStudentSignup }) {
let panelColor = "panel-default";
let canAdd = true;
+ let shortDuration = 600;
const spareCapacity = calcSpareCapacity(appointment);
if (currentUser.isStaff) {
if (appointment.helper && appointment.status === "hidden") {
panelColor = "panel-danger";
+ if (appointment.duration <= shortDuration) {
+ panelColor = "panel-danger-short";
+ }
} else if (appointment.helper && appointment.helper.id === currentUser.id) {
panelColor = "panel-primary";
+ if (appointment.duration <= shortDuration) {
+ panelColor = "panel-primary-short";
+ }
} else if (currentUser.isStaff && !appointment.helper) {
panelColor = "panel-warning";
+ if (appointment.duration <= shortDuration) {
+ panelColor = "panel-warning-short";
+ }
}
} else {
if (appointment.signups.some(({ user }) => user && user.id === currentUser.id)) {
panelColor = "panel-success";
canAdd = false;
+ if (appointment.duration <= shortDuration) {
+ panelColor = "panel-success-short";
+ }
} else if (spareCapacity === 0) {
panelColor = "panel-danger";
+ if (appointment.duration <= shortDuration) {
+ panelColor = "panel-danger-short";
+ }
+ } else if (appointment.duration <= shortDuration) {
+ panelColor = "panel-default-short";
}
}
diff --git a/oh_queue/views.py b/oh_queue/views.py
index 4dc92e7..0701526 100644
--- a/oh_queue/views.py
+++ b/oh_queue/views.py
@@ -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',
@@ -922,6 +928,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())
@@ -940,13 +947,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"],
|