Skip to content
Snippets Groups Projects
Commit df8632fd authored by Nadja Geisler's avatar Nadja Geisler :sunny:
Browse files

Merge branch '520-improve-scheduling' into 'main'

Improve scheduling

Closes #209, #201, and #215

See merge request !215
parents 2506327c d5fad1a6
No related branches found
No related tags found
1 merge request!215Improve scheduling
Pipeline #228476 passed
...@@ -14,6 +14,9 @@ from AKModel.models import Event, AKCategory, AKRequirement, Room ...@@ -14,6 +14,9 @@ from AKModel.models import Event, AKCategory, AKRequirement, Room
class DateTimeInput(forms.DateInput): class DateTimeInput(forms.DateInput):
"""
Simple widget for datetime input fields using the HTML5 datetime-local input type
"""
input_type = 'datetime-local' input_type = 'datetime-local'
......
...@@ -367,7 +367,7 @@ class AK(models.Model): ...@@ -367,7 +367,7 @@ class AK(models.Model):
@property @property
def details(self): def details(self):
""" """
Generate a detailled string representation, e.g., for usage in scheduling Generate a detailed string representation, e.g., for usage in scheduling
:return: string representation of that AK with all details :return: string representation of that AK with all details
:rtype: str :rtype: str
""" """
...@@ -376,15 +376,19 @@ class AK(models.Model): ...@@ -376,15 +376,19 @@ class AK(models.Model):
from AKModel.availability.models import Availability from AKModel.availability.models import Availability
availabilities = ', \n'.join(f'{a.simplified}' for a in Availability.objects.select_related('event') availabilities = ', \n'.join(f'{a.simplified}' for a in Availability.objects.select_related('event')
.filter(ak=self)) .filter(ak=self))
return f"""{self.name}{" (R)" if self.reso else ""}: detail_string = f"""{self.name}{" (R)" if self.reso else ""}:
{self.owners_list} {self.owners_list}
{_('Interest')}: {self.interest} {_('Interest')}: {self.interest}"""
{_("Requirements")}: {", ".join(str(r) for r in self.requirements.all())} if self.requirements.count() > 0:
{_("Conflicts")}: {", ".join(str(c) for c in self.conflicts.all())} detail_string += f"\n{_('Requirements')}: {', '.join(str(r) for r in self.requirements.all())}"
{_("Prerequisites")}: {", ".join(str(p) for p in self.prerequisites.all())} if self.conflicts.count() > 0:
{_("Availabilities")}: \n{availabilities}""" detail_string += f"\n{_('Conflicts')}: {', '.join(str(c) for c in self.conflicts.all())}"
if self.prerequisites.count() > 0:
detail_string += f"\n{_('Prerequisites')}: {', '.join(str(p) for p in self.prerequisites.all())}"
detail_string += f"\n{_('Availabilities')}: \n{availabilities}"
return detail_string
@property @property
def owners_list(self): def owners_list(self):
......
...@@ -83,6 +83,7 @@ class PlanScreenView(PlanIndexView): ...@@ -83,6 +83,7 @@ class PlanScreenView(PlanIndexView):
return redirect(reverse_lazy("plan:plan_overview", kwargs={"event_slug": self.event.slug})) return redirect(reverse_lazy("plan:plan_overview", kwargs={"event_slug": self.event.slug}))
return s return s
# pylint: disable=attribute-defined-outside-init
def get_queryset(self): def get_queryset(self):
now = datetime.now().astimezone(self.event.timezone) now = datetime.now().astimezone(self.event.timezone)
# Wall during event: Adjust, show only parts in the future # Wall during event: Adjust, show only parts in the future
......
...@@ -80,8 +80,8 @@ def check_capacity_for_slot(slot: AKSlot): ...@@ -80,8 +80,8 @@ def check_capacity_for_slot(slot: AKSlot):
:rtype: ConstraintViolation or None :rtype: ConstraintViolation or None
""" """
# If slot is scheduled in a room # If slot is scheduled in a room and interest was specified
if slot.room and slot.room.capacity >= 0: if slot.room and slot.room.capacity >= 0 and slot.ak.interest >= 0:
# Create a violation if interest exceeds room capacity # Create a violation if interest exceeds room capacity
if slot.room.capacity < slot.ak.interest: if slot.room.capacity < slot.ak.interest:
c = ConstraintViolation( c = ConstraintViolation(
......
...@@ -23,26 +23,31 @@ ...@@ -23,26 +23,31 @@
const callback_success = function(response) { const callback_success = function(response) {
let table_html = ''; let table_html = '';
let unresolved_constraint_violations = 0;
if(response.length > 0) { if(response.length > 0) {
// Update violation count badge
$('#violationCountBadge').html(response.length).removeClass('bg-success').addClass('bg-warning');
// Update violations table // Update violations table
for(let i=0;i<response.length;i++) { for(let i=0;i<response.length;i++) {
if(response[i].manually_resolved) if(response[i].manually_resolved) {
table_html += '<tr class="text-muted"><td class="nowrap">{% fa6_icon "check" "fas" %}</td>'; table_html += '<tr class="text-muted"><td class="nowrap">{% fa6_icon "check" "fas" %}</td>';
else }
else {
table_html += '<tr><td></td>'; table_html += '<tr><td></td>';
unresolved_constraint_violations++;
}
table_html += "<td>" + response[i].level_display + "</td><td>" + response[i].type_display + "</td><td>" + response[i].details + "</td><td class='nowrap'>" + response[i].timestamp_display + "</td><td><a href='" + response[i].edit_url + "'><i class='btn btn-primary fa fa-pen'></i></a></td></tr>"; table_html += "<td>" + response[i].level_display + "</td><td>" + response[i].type_display + "</td><td>" + response[i].details + "</td><td class='nowrap'>" + response[i].timestamp_display + "</td><td><a href='" + response[i].edit_url + "'><i class='btn btn-primary fa fa-pen'></i></a></td></tr>";
} }
} }
else { else {
// Update violation count badge
$('#violationCountBadge').html(0).removeClass('bg-warning').addClass('bg-success');
// Update violations table // Update violations table
table_html ='<tr class="text-muted"><td colspan="5" class="text-center">{% trans "No violations" %}</td></tr>' table_html ='<tr class="text-muted"><td colspan="5" class="text-center">{% trans "No violations" %}</td></tr>'
} }
// Update violation count badge
if(unresolved_constraint_violations > 0)
$('#violationCountBadge').html(unresolved_constraint_violations).removeClass('bg-success').addClass('bg-warning');
else
$('#violationCountBadge').html(0).removeClass('bg-warning').addClass('bg-success');
// Show violation list (potentially empty) in violations table // Show violation list (potentially empty) in violations table
$('#violationsTableBody').html(table_html); $('#violationsTableBody').html(table_html);
......
...@@ -215,20 +215,24 @@ ...@@ -215,20 +215,24 @@
if(response.length > 0) { if(response.length > 0) {
// Update violations table // Update violations table
for(let i=0;i<response.length;i++) { for(let i=0;i<response.length;i++) {
if(response[i].manually_resolved) let icon_html = '';
table_html += '<tr class="text-muted"><td class="nowrap">{% fa6_icon "check" "fas" %} '; let muted_html = '';
if(response[i].manually_resolved) {
icon_html = '{% fa6_icon "check" "fas" %} ';
muted_html = 'text-muted';
}
else { else {
table_html += '<tr><td>';
unresolved_violations_count++; unresolved_violations_count++;
} }
if(response[i].level_display==='{% trans "Violation" %}') if(response[i].level_display==='{% trans "Violation" %}')
table_html += '{% fa6_icon "exclamation-triangle" "fas" %}'; icon_html += '{% fa6_icon "exclamation-triangle" "fas" %}';
else else
table_html += '{% fa6_icon "info-circle" "fas" %}'; icon_html += '{% fa6_icon "info-circle" "fas" %}';
table_html += '<tr class="'+ muted_html+ '"><td class="nowrap">' + icon_html;
table_html += "</td><td class='small'>" + response[i].type_display + "</td></tr>"; table_html += "</td><td class='small'>" + response[i].type_display + "</td></tr>";
table_html += "<tr><td colspan='2' class='small'>" + response[i].details + "</td></tr>" table_html += "<tr class='" + muted_html + "'><td colspan='2' class='small'>" + response[i].details + "</td></tr>"
} }
} }
else { else {
...@@ -238,7 +242,7 @@ ...@@ -238,7 +242,7 @@
// Update violation count badge // Update violation count badge
if(unresolved_violations_count > 0) if(unresolved_violations_count > 0)
$('#violationCountBadge').html(response.length).removeClass('bg-success').addClass('bg-warning'); $('#violationCountBadge').html(unresolved_violations_count).removeClass('bg-success').addClass('bg-warning');
else else
$('#violationCountBadge').html(0).removeClass('bg-warning').addClass('bg-success'); $('#violationCountBadge').html(0).removeClass('bg-warning').addClass('bg-success');
...@@ -358,7 +362,7 @@ ...@@ -358,7 +362,7 @@
{% endfor %} {% endfor %}
</div> </div>
<div class="tab-pane fade" id="violations"> <div class="tab-pane fade" id="violations">
<table class="table table-striped mt-4 mb-4"> <table class="table mt-4 mb-4">
<thead> <thead>
<tr> <tr>
<th>{% trans "Level" %}</th> <th>{% trans "Level" %}</th>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment