Skip to content

Commit ae7083f

Browse files
stephenfinfstachura
authored andcommitted
views: Add patch labels to web UI
Nothing too complicated here. The forms we have for this need some serious cleanup/beautification, but that's a problem for another day.
1 parent 26233bf commit ae7083f

6 files changed

Lines changed: 67 additions & 1 deletion

File tree

‎patchwork/forms.py‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from patchwork.models import Bundle
1616
from patchwork.models import Patch
17+
from patchwork.models import Label
1718
from patchwork.models import State
1819
from patchwork.models import UserProfile
1920

@@ -144,10 +145,16 @@ def __init__(self, instance=None, project=None, *args, **kwargs):
144145
widget=forms.Select(attrs={'class': 'change-property-delegate'}),
145146
required=False,
146147
)
148+
self.fields['labels'] = forms.ModelMultipleChoiceField(
149+
queryset=Label.objects.filter(
150+
Q(project=project) | Q(project=None)
151+
),
152+
required=False,
153+
)
147154

148155
class Meta:
149156
model = Patch
150-
fields = ['state', 'archived', 'delegate']
157+
fields = ['state', 'archived', 'delegate', 'labels']
151158
widgets = {
152159
'state': forms.Select(attrs={'class': 'change-property-state'}),
153160
'archived': forms.CheckboxInput(
@@ -223,6 +230,12 @@ def __init__(self, project, *args, **kwargs):
223230
label='Delegate to',
224231
required=False,
225232
)
233+
self.fields['labels'] = forms.ModelMultipleChoiceField(
234+
queryset=Label.objects.filter(
235+
Q(project=project) | Q(project=None)
236+
),
237+
required=False,
238+
)
226239
self.fields['state'] = OptionalModelChoiceField(
227240
queryset=State.objects.all(),
228241
placeholder='Change state',
@@ -254,6 +267,13 @@ def save(self, instance, commit=True):
254267

255268
if commit:
256269
instance.save()
270+
271+
for f in opts.many_to_many:
272+
if f.name not in data:
273+
continue
274+
275+
getattr(instance, f.name).add(*data[f.name])
276+
257277
return instance
258278

259279

‎patchwork/templates/patchwork/partials/patch-forms.html‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
{{ patch_form.archived.errors }}
1414
{{ patch_form.archived.label_tag }} {{ patch_form.archived }}
1515
</div>
16+
<div id="patch-form-labels">
17+
{{ patch_form.labels.errors }}
18+
{{ patch_form.labels }}
19+
</div>
1620
<button class="patch-form-submit btn btn-primary" name="action" value="update">
1721
Update
1822
</button>

‎patchwork/templates/patchwork/partials/patch-list.html‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
<a href="{% url 'patch-detail' project_id=project.linkname msgid=patch.encoded_msgid %}">
173173
{{ patch.name|default:"[no subject]"|truncatechars:100 }}
174174
</a>
175+
{{ patch|patch_labels }}
175176
</td>
176177
<td id="patch-series:{{patch.id}}">
177178
{% if patch.series %}

‎patchwork/templates/patchwork/submission.html‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ <h1>{{ submission.name }}</h1>
130130
</td>
131131
</tr>
132132
{% endif %}
133+
<tr>
134+
<th>Labels</th>
135+
<td>
136+
{{ submission|patch_labels }}
137+
</td>
138+
</tr>
133139
</table>
134140

135141
<form id="patch-list-form" method="POST">

‎patchwork/templatetags/patch.py‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,34 @@ def patch_commit_display(patch):
8383
return mark_safe( # noqa: S308
8484
'<a href="%s">%s</a>' % (escape(fmt.format(commit)), escape(commit))
8585
)
86+
87+
88+
@register.filter(name='patch_labels')
89+
def patch_labels(patch):
90+
91+
def text_color(hex_color):
92+
"""Generate the ideal text color given a background color.
93+
94+
From https://www.w3.org/TR/AERT/#color-contrast
95+
"""
96+
red, green, blue = [
97+
int(hex_color.lstrip('#')[i : i + 2], 16) for i in (0, 2, 4)
98+
]
99+
brightness = (red * 299 + green * 587 + blue * 114) / 1000
100+
101+
return '#000' if brightness >= 123 else '#fff'
102+
103+
output = []
104+
for label in patch.labels.all():
105+
style = 'background-color: %s; color: %s' % (
106+
label.color,
107+
text_color(label.color),
108+
)
109+
output.append(
110+
'<span class="label" style="%s">%s</span>'
111+
% (style, escape(label.name))
112+
)
113+
114+
# Label name is escaped above. Color is formatted in a way that
115+
# does not permit XSS
116+
return mark_safe(''.join(output)) # noqa: S308

‎patchwork/views/__init__.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from patchwork.forms import MultiplePatchForm
1515
from patchwork.models import Bundle
1616
from patchwork.models import BundlePatch
17+
from patchwork.models import Label
1718
from patchwork.models import Patch
1819
from patchwork.models import Project
1920
from patchwork.models import Check
@@ -333,6 +334,9 @@ def generic_list(
333334
),
334335
)
335336
)
337+
patches = patches.prefetch_related(
338+
Prefetch('labels', queryset=Label.objects.only('name', 'color')),
339+
)
336340

337341
# annotate with tag counts
338342
patches = patches.with_tag_counts(project)

0 commit comments

Comments
 (0)