From: Stephen Finucane <[email protected]>

Nothing too complicated here. The forms we have for this need some
serious cleanup/beautification, but that's a problem for another day.

Signed-off-by: Franciszek Stachura <[email protected]>
---
v3:
- Also prefetch label color
- Moved some code to patch-form partial
---
 patchwork/forms.py                            | 22 ++++++++++++++-
 .../patchwork/partials/patch-forms.html       |  4 +++
 .../patchwork/partials/patch-list.html        |  1 +
 patchwork/templates/patchwork/submission.html |  6 ++++
 patchwork/templatetags/patch.py               | 28 +++++++++++++++++++
 patchwork/views/__init__.py                   |  4 +++
 6 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/patchwork/forms.py b/patchwork/forms.py
index 1e62368a..19d19d64 100644
--- a/patchwork/forms.py
+++ b/patchwork/forms.py
@@ -14,6 +14,7 @@ from django.template.backends import django as 
django_template_backend
 
 from patchwork.models import Bundle
 from patchwork.models import Patch
+from patchwork.models import Label
 from patchwork.models import State
 from patchwork.models import UserProfile
 
@@ -144,10 +145,16 @@ class PatchForm(forms.ModelForm):
             widget=forms.Select(attrs={'class': 'change-property-delegate'}),
             required=False,
         )
+        self.fields['labels'] = forms.ModelMultipleChoiceField(
+            queryset=Label.objects.filter(
+                Q(project=project) | Q(project=None)
+            ),
+            required=False,
+        )
 
     class Meta:
         model = Patch
-        fields = ['state', 'archived', 'delegate']
+        fields = ['state', 'archived', 'delegate', 'labels']
         widgets = {
             'state': forms.Select(attrs={'class': 'change-property-state'}),
             'archived': forms.CheckboxInput(
@@ -223,6 +230,12 @@ class MultiplePatchForm(forms.Form):
             label='Delegate to',
             required=False,
         )
+        self.fields['labels'] = forms.ModelMultipleChoiceField(
+            queryset=Label.objects.filter(
+                Q(project=project) | Q(project=None)
+            ),
+            required=False,
+        )
         self.fields['state'] = OptionalModelChoiceField(
             queryset=State.objects.all(),
             placeholder='Change state',
@@ -254,6 +267,13 @@ class MultiplePatchForm(forms.Form):
 
         if commit:
             instance.save()
+
+        for f in opts.many_to_many:
+            if f.name not in data:
+                continue
+
+            getattr(instance, f.name).add(*data[f.name])
+
         return instance
 
 
diff --git a/patchwork/templates/patchwork/partials/patch-forms.html 
b/patchwork/templates/patchwork/partials/patch-forms.html
index 80f82815..2dee8230 100644
--- a/patchwork/templates/patchwork/partials/patch-forms.html
+++ b/patchwork/templates/patchwork/partials/patch-forms.html
@@ -13,6 +13,10 @@
       {{ patch_form.archived.errors }}
       {{ patch_form.archived.label_tag }} {{ patch_form.archived }}
     </div>
+    <div id="patch-form-labels">
+      {{ patch_form.labels.errors }}
+      {{ patch_form.labels }}
+    </div>
     <button class="patch-form-submit btn btn-primary" name="action" 
value="update">
       Update
     </button>
diff --git a/patchwork/templates/patchwork/partials/patch-list.html 
b/patchwork/templates/patchwork/partials/patch-list.html
index 981ceee5..97f541f7 100644
--- a/patchwork/templates/patchwork/partials/patch-list.html
+++ b/patchwork/templates/patchwork/partials/patch-list.html
@@ -172,6 +172,7 @@
           <a href="{% url 'patch-detail' project_id=project.linkname 
msgid=patch.encoded_msgid %}">
             {{ patch.name|default:"[no subject]"|truncatechars:100 }}
           </a>
+          {{ patch|patch_labels }}
         </td>
         <td id="patch-series:{{patch.id}}">
 {% if patch.series %}
diff --git a/patchwork/templates/patchwork/submission.html 
b/patchwork/templates/patchwork/submission.html
index cd74491c..f65480ab 100644
--- a/patchwork/templates/patchwork/submission.html
+++ b/patchwork/templates/patchwork/submission.html
@@ -130,6 +130,12 @@
     </td>
   </tr>
 {% endif %}
+  <tr>
+    <th>Labels</th>
+    <td>
+    {{ submission|patch_labels }}
+    </td>
+  </tr>
 </table>
 
 <form id="patch-list-form" method="POST">
diff --git a/patchwork/templatetags/patch.py b/patchwork/templatetags/patch.py
index c22dfa33..a9902d49 100644
--- a/patchwork/templatetags/patch.py
+++ b/patchwork/templatetags/patch.py
@@ -70,3 +70,31 @@ def patch_commit_display(patch):
     return mark_safe(
         '<a href="%s">%s</a>' % (escape(fmt.format(commit)), escape(commit))
     )
+
+
[email protected](name='patch_labels')
+def patch_labels(patch):
+
+    def text_color(hex_color):
+        """Generate the ideal text color given a background color.
+
+        From https://www.w3.org/TR/AERT/#color-contrast
+        """
+        red, green, blue = [
+            int(hex_color.lstrip('#')[i : i + 2], 16) for i in (0, 2, 4)
+        ]
+        brightness = (red * 299 + green * 587 + blue * 114) / 1000
+
+        return '#000' if brightness >= 123 else '#fff'
+
+    output = []
+    for label in patch.labels.all():
+        style = 'background-color: %s; color: %s' % (
+            label.color,
+            text_color(label.color),
+        )
+        output.append(
+            '<span class="label" style="%s">%s</span>' % (style, label.name)
+        )
+
+    return mark_safe(''.join(output))
diff --git a/patchwork/views/__init__.py b/patchwork/views/__init__.py
index 92adbbcc..2685d2a5 100644
--- a/patchwork/views/__init__.py
+++ b/patchwork/views/__init__.py
@@ -14,6 +14,7 @@ from patchwork.forms import CreateBundleForm
 from patchwork.forms import MultiplePatchForm
 from patchwork.models import Bundle
 from patchwork.models import BundlePatch
+from patchwork.models import Label
 from patchwork.models import Patch
 from patchwork.models import Project
 from patchwork.models import Check
@@ -320,6 +321,9 @@ def generic_list(
             ),
         )
     )
+    patches = patches.prefetch_related(
+        Prefetch('labels', queryset=Label.objects.only('name', 'color')),
+    )
 
     paginator = Paginator(request, patches)
 
-- 
2.55.0

_______________________________________________
Patchwork mailing list
[email protected]
https://lists.ozlabs.org/listinfo/patchwork

Reply via email to