Add support for detecting and displaying AD conflicts.
- Legacy-Id: 18046
This commit is contained in:
parent
3b31ed9ad1
commit
44cbfca7bd
|
@ -1013,11 +1013,13 @@ class EditTests(TestCase):
|
|||
|
||||
constraints = e.find(".constraints > span")
|
||||
s_other = s2 if s == s1 else s1
|
||||
self.assertEqual(len(constraints), 2)
|
||||
self.assertEqual(len(constraints), 3)
|
||||
self.assertEqual(constraints.eq(0).attr("data-sessions"), str(s_other.pk))
|
||||
self.assertEqual(constraints.eq(0).find(".fa-user-o").parent().text(), "1") # 1 person in the constraint
|
||||
self.assertEqual(constraints.eq(1).attr("data-sessions"), str(s_other.pk))
|
||||
self.assertEqual(constraints.find(".encircled").text(), "1" if s_other == s2 else "-1")
|
||||
self.assertEqual(constraints.find(".fa-user-o").parent().text(), "1") # 1 person in the constraint
|
||||
self.assertEqual(constraints.eq(1).find(".encircled").text(), "1" if s_other == s2 else "-1")
|
||||
self.assertEqual(constraints.eq(2).attr("data-sessions"), str(s_other.pk))
|
||||
self.assertEqual(constraints.eq(2).find(".encircled").text(), "AD")
|
||||
|
||||
# session info for the panel
|
||||
self.assertIn(str(round(s.requested_duration.total_seconds() / 60.0 / 60, 1)), e.find(".session-info .title").text())
|
||||
|
|
|
@ -24,7 +24,7 @@ from ietf.group.models import Group, Role
|
|||
from ietf.group.utils import can_manage_materials
|
||||
from ietf.name.models import SessionStatusName, ConstraintName
|
||||
from ietf.nomcom.utils import DISQUALIFYING_ROLE_QUERY_EXPRESSION
|
||||
from ietf.person.models import Email
|
||||
from ietf.person.models import Person, Email
|
||||
from ietf.secr.proceedings.proc_utils import import_audio_files
|
||||
|
||||
def session_time_for_sorting(session, use_meeting_date):
|
||||
|
@ -319,12 +319,27 @@ def reverse_editor_label(label):
|
|||
else:
|
||||
return reverse_sign + label
|
||||
|
||||
def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions):
|
||||
constraints = Constraint.objects.filter(meeting=meeting).prefetch_related('target', 'person', 'timeranges')
|
||||
|
||||
# process constraint names
|
||||
def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions, responsible_ad_for_group):
|
||||
# process constraint names - we synthesize extra names to be able
|
||||
# to treat the concepts in the same manner as the modelled ones
|
||||
constraint_names = {n.pk: n for n in ConstraintName.objects.all()}
|
||||
|
||||
joint_with_groups_constraint_name = ConstraintName(
|
||||
slug='joint_with_groups',
|
||||
name="Joint session with",
|
||||
editor_label="<i class=\"fa fa-clone\"></i>",
|
||||
order=8,
|
||||
)
|
||||
constraint_names[joint_with_groups_constraint_name.slug] = joint_with_groups_constraint_name
|
||||
|
||||
ad_constraint_name = ConstraintName(
|
||||
slug='responsible_ad',
|
||||
name="Responsible AD",
|
||||
editor_label="<span class=\"encircled\">AD</span>",
|
||||
order=9,
|
||||
)
|
||||
constraint_names[ad_constraint_name.slug] = ad_constraint_name
|
||||
|
||||
for n in list(constraint_names.values()):
|
||||
# add reversed version of the name
|
||||
reverse_n = ConstraintName(
|
||||
|
@ -338,12 +353,23 @@ def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions):
|
|||
n.countless_formatted_editor_label = format_html(n.formatted_editor_label, count="") if "{count}" in n.formatted_editor_label else n.formatted_editor_label
|
||||
|
||||
# convert human-readable rules in the database to constraints on actual sessions
|
||||
constraints = list(Constraint.objects.filter(meeting=meeting).prefetch_related('target', 'person', 'timeranges'))
|
||||
|
||||
# synthesize AD constraints - we can treat them as a special kind of 'bethere'
|
||||
ad_person_lookup = {p.pk: p for p in Person.objects.filter(pk__in=set(responsible_ad_for_group.values()))}
|
||||
groups_at_meeting = {s.group for s in sessions}
|
||||
for group in groups_at_meeting:
|
||||
ad = ad_person_lookup.get(responsible_ad_for_group.get(group.pk))
|
||||
if ad is not None:
|
||||
constraints.append(Constraint(meeting=meeting, source=group, person=ad, name=ad_constraint_name))
|
||||
|
||||
# process must not be scheduled at the same time constraints
|
||||
constraints_for_sessions = defaultdict(list)
|
||||
|
||||
person_needed_for_groups = defaultdict(set)
|
||||
person_needed_for_groups = {cn.slug: defaultdict(set) for cn in constraint_names.values()}
|
||||
for c in constraints:
|
||||
if c.name_id == 'bethere' and c.person_id is not None:
|
||||
person_needed_for_groups[c.person_id].add(c.source_id)
|
||||
if c.person_id is not None:
|
||||
person_needed_for_groups[c.name_id][c.person_id].add(c.source_id)
|
||||
|
||||
sessions_for_group = defaultdict(list)
|
||||
for s in sessions:
|
||||
|
@ -367,7 +393,7 @@ def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions):
|
|||
reverse_constraints.append(c)
|
||||
|
||||
elif c.person_id:
|
||||
for g in person_needed_for_groups.get(c.person_id):
|
||||
for g in person_needed_for_groups[c.name_id].get(c.person_id):
|
||||
add_group_constraints(c.source_id, g, c.name_id, c.person_id)
|
||||
|
||||
for c in reverse_constraints:
|
||||
|
@ -394,17 +420,7 @@ def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions):
|
|||
for s_pk in sessions_for_group.get(group_pk, []):
|
||||
formatted_constraints_for_sessions[s_pk][constraint_names[cn_pk]] = [format_constraint(c) for c in cs]
|
||||
|
||||
# it's easier for the rest of the code if we treat
|
||||
# joint_with_groups as a constraint, even if it's not modelled as
|
||||
# one
|
||||
joint_with_groups_constraint_name = ConstraintName(
|
||||
slug='joint_with_groups',
|
||||
name="Joint session with",
|
||||
editor_label="<i class=\"fa fa-clone\"></i>",
|
||||
order=8,
|
||||
)
|
||||
joint_with_groups_constraint_name.formatted_editor_label = mark_safe(joint_with_groups_constraint_name.editor_label)
|
||||
joint_with_groups_constraint_name.countless_formatted_editor_label = joint_with_groups_constraint_name.formatted_editor_label
|
||||
# synthesize joint_with_groups constraints
|
||||
for s in sessions:
|
||||
joint_groups = s.joint_with_groups.all()
|
||||
if joint_groups:
|
||||
|
|
|
@ -588,20 +588,23 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None):
|
|||
|
||||
# dig out historic AD names
|
||||
ad_names = {}
|
||||
ad_pks = {}
|
||||
session_groups = set(s.group for s in sessions if s.group and s.group.parent and s.group.parent.type_id == 'area')
|
||||
meeting_time = datetime.datetime.combine(meeting.date, datetime.time(0, 0, 0))
|
||||
|
||||
for group_id, history_time, name in Person.objects.filter(rolehistory__name='ad', rolehistory__group__group__in=session_groups, rolehistory__group__time__lte=meeting_time).values_list('rolehistory__group__group', 'rolehistory__group__time', 'name').order_by('rolehistory__group__time'):
|
||||
for group_id, history_time, name, pk in Person.objects.filter(rolehistory__name='ad', rolehistory__group__group__in=session_groups, rolehistory__group__time__lte=meeting_time).values_list('rolehistory__group__group', 'rolehistory__group__time', 'name', 'pk').order_by('rolehistory__group__time'):
|
||||
ad_names[group_id] = plain_name(name)
|
||||
ad_pks[group_id] = pk
|
||||
|
||||
for group_id, name in Person.objects.filter(role__name='ad', role__group__in=session_groups, role__group__time__lte=meeting_time).values_list('role__group', 'name'):
|
||||
for group_id, name, pk in Person.objects.filter(role__name='ad', role__group__in=session_groups, role__group__time__lte=meeting_time).values_list('role__group', 'name', 'pk'):
|
||||
ad_names[group_id] = plain_name(name)
|
||||
ad_pks[group_id] = pk
|
||||
|
||||
# requesters
|
||||
requested_by_lookup = {p.pk: p for p in Person.objects.filter(pk__in=set(s.requested_by for s in sessions if s.requested_by))}
|
||||
|
||||
# constraints
|
||||
constraints_for_sessions, formatted_constraints_for_sessions, constraint_names = preprocess_constraints_for_meeting_schedule_editor(meeting, sessions)
|
||||
constraints_for_sessions, formatted_constraints_for_sessions, constraint_names = preprocess_constraints_for_meeting_schedule_editor(meeting, sessions, ad_pks)
|
||||
|
||||
sessions_for_group = defaultdict(list)
|
||||
for s in sessions:
|
||||
|
|
|
@ -1089,7 +1089,7 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
|
|||
.edit-meeting-schedule .formatted-constraints .encircled {
|
||||
border: 1px solid #000;
|
||||
border-radius: 1em;
|
||||
min-width: 1.3em;
|
||||
padding: 0 0.3em;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue