Rework the new meeting editor label formatting to store the icon

references directly in the database as HTML.

Rework the label update migration to take this into account (can be
rerun by running "ietf/manage.py migrate name 0011 --fake" first).

Add a little bit of support for the recently added constraints types -
the JS does not hint about them, but they do show up without looking
silly.
 - Legacy-Id: 18033
This commit is contained in:
Ole Laursen 2020-06-22 17:33:54 +00:00
parent ab178173f4
commit 49d4be8d17
4 changed files with 44 additions and 18 deletions

View file

@ -14,6 +14,7 @@ from django.conf import settings
from django.template.loader import render_to_string
from django.db.models.expressions import Subquery, OuterRef
from django.utils.html import format_html
from django.utils.safestring import mark_safe
import debug # pyflakes:ignore
@ -309,16 +310,14 @@ def data_for_meetings_overview(meetings, interim_status=None):
return meetings
def format_constraint_editor_label(label, inner_fmt="{}"):
m = re.match(r'(.*)\(person\)(.*)', label)
if m:
return format_html("{}<i class=\"fa fa-user-o\"></i>{}", format_html(inner_fmt, m.groups()[0]), m.groups()[1])
def reverse_editor_label(label):
reverse_sign = "-"
m = re.match(r"\(([^()]+)\)", label)
m = re.match(r"(<[^>]+>)([^<].*)", label)
if m:
return format_html("<span class=\"encircled\">{}</span>", format_html(inner_fmt, m.groups()[0]))
return format_html(inner_fmt, label)
return m.groups()[0] + reverse_sign + m.groups()[1]
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')
@ -332,10 +331,10 @@ def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions):
slug=n.slug + "-reversed",
name="{} - reversed".format(n.name),
)
reverse_n.formatted_editor_label = format_constraint_editor_label(n.editor_label, inner_fmt="-{}")
reverse_n.formatted_editor_label = mark_safe(reverse_editor_label(n.editor_label))
constraint_names[reverse_n.slug] = reverse_n
n.formatted_editor_label = format_constraint_editor_label(n.editor_label)
n.formatted_editor_label = mark_safe(n.editor_label)
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
@ -362,7 +361,7 @@ def preprocess_constraints_for_meeting_schedule_editor(meeting, sessions):
seen_forward_constraints_for_groups = set()
for c in constraints:
if c.target_id:
if c.target_id and c.name_id != 'wg_adjacent':
add_group_constraints(c.source_id, c.target_id, c.name_id, c.person_id)
seen_forward_constraints_for_groups.add((c.source_id, c.target_id, c.name_id))
reverse_constraints.append(c)
@ -395,4 +394,20 @@ 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
for s in sessions:
joint_groups = s.joint_with_groups.all()
if joint_groups:
formatted_constraints_for_sessions[s.pk][joint_with_groups_constraint_name] = [g.acronym for g in joint_groups]
return constraints_for_sessions, formatted_constraints_for_sessions, constraint_names

View file

@ -470,7 +470,7 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None):
requested_time=True,
requested_by=True,
).exclude(current_status__in=['notmeet', 'disappr', 'deleted', 'apprw']).prefetch_related(
'resources', 'group', 'group__parent', 'group__type',
'resources', 'group', 'group__parent', 'group__type', 'joint_with_groups',
)
if request.method == 'POST':
@ -507,14 +507,14 @@ def edit_meeting_schedule(request, num=None, owner=None, name=None):
for a in assignments:
assignments_by_session[a.session_id].append(a)
# Prepare timeslot layout, making a timeline per day scaled in
# browser rem units to ensure that everything lines up even if the
# timeslots are not the same in the different rooms
# prepare timeslot layout
min_duration = min(t.duration for t in timeslots_qs)
max_duration = max(t.duration for t in timeslots_qs)
def timedelta_to_css_ems(timedelta):
# we scale the session and slots a bit according to their
# length for an added visual clue
capped_min_d = max(min_duration, datetime.timedelta(minutes=30))
capped_max_d = min(max_duration, datetime.timedelta(hours=4))
capped_timedelta = min(max(capped_min_d, timedelta), capped_max_d)

View file

@ -1,6 +1,6 @@
# Copyright The IETF Trust 2020, All Rights Reserved
from django.db import migrations
from django.db import migrations, models
class Migration(migrations.Migration):
@ -12,7 +12,13 @@ class Migration(migrations.Migration):
ConstraintName = apps.get_model('name', 'ConstraintName')
for cn in ConstraintName.objects.all():
cn.editor_label = {
'bethere': "(person){count}",
'bethere': "<i class=\"fa fa-user-o\"></i>{count}",
'wg_adjacent': "<i class=\"fa fa-step-forward\"></i>",
'conflict': "<span class=\"encircled\">1</span>",
'conflic2': "<span class=\"encircled\">2</span>",
'conflic3': "<span class=\"encircled\">3</span>",
'time_relation': "&Delta;",
'timerange': "<i class=\"fa fa-calendar-o\"></i>",
}.get(cn.slug, cn.editor_label)
cn.order = {
@ -31,5 +37,10 @@ class Migration(migrations.Migration):
pass
operations = [
migrations.AlterField(
model_name='constraintname',
name='editor_label',
field=models.CharField(blank=True, help_text='Very short label for producing warnings inline in the sessions in the schedule editor.', max_length=64),
),
migrations.RunPython(update_editor_labels, noop, elidable=True),
]

View file

@ -69,7 +69,7 @@ class TimeSlotTypeName(NameModel):
class ConstraintName(NameModel):
"""conflict, conflic2, conflic3, bethere, timerange, time_relation, wg_adjacent"""
penalty = models.IntegerField(default=0, help_text="The penalty for violating this kind of constraint; for instance 10 (small penalty) or 10000 (large penalty)")
editor_label = models.CharField(max_length=32, blank=True, help_text="Very short label for producing warnings inline in the sessions in the schedule editor.")
editor_label = models.CharField(max_length=64, blank=True, help_text="Very short label for producing warnings inline in the sessions in the schedule editor.")
class TimerangeName(NameModel):
"""(monday|tuesday|wednesday|thursday|friday)-(morning|afternoon-early|afternoon-late)"""
class LiaisonStatementPurposeName(NameModel):