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:
parent
ab178173f4
commit
49d4be8d17
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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': "Δ",
|
||||
'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),
|
||||
]
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue