From fe7c8685cef2abc4937c2718723b5d8653b17764 Mon Sep 17 00:00:00 2001 From: andrepapoti Date: Mon, 22 Apr 2024 15:25:34 -0300 Subject: [PATCH 1/8] views: add series-list view This view is meant to give a quickoverview on a project since some of them can have hundreds of patches actives. This view also allows the user to apply changes on all of the series patches at once Signed-off-by: andrepapoti --- htdocs/css/style.css | 6 + .../templates/patchwork/series-list.html | 106 ++++++++++++++++++ patchwork/urls.py | 10 ++ patchwork/views/patch.py | 6 + patchwork/views/series.py | 44 ++++++++ 5 files changed, 172 insertions(+) create mode 100644 patchwork/templates/patchwork/series-list.html diff --git a/htdocs/css/style.css b/htdocs/css/style.css index 268a8c372..cba33cf94 100644 --- a/htdocs/css/style.css +++ b/htdocs/css/style.css @@ -407,6 +407,12 @@ span.p_mod { color: #a020f0; } font-weight: bold; } +/* series */ +a.series-list-header { + color: inherit; /* Inherit color from parent element */ + text-decoration: none; /* Optional: removes underline */ +} + /* bundles */ table.bundlelist { margin-top: 2em; diff --git a/patchwork/templates/patchwork/series-list.html b/patchwork/templates/patchwork/series-list.html new file mode 100644 index 000000000..f157c6ca2 --- /dev/null +++ b/patchwork/templates/patchwork/series-list.html @@ -0,0 +1,106 @@ +{% extends "base.html" %} + +{% load person %} +{% load static %} + +{% block title %}{{project.name}}{% endblock %} +{% block series_active %}active{% endblock %} + +{% block body %} + +{% load person %} +{% load listurl %} +{% load patch %} +{% load project %} +{% load static %} + +{% include "patchwork/partials/pagination.html" %} + + + + + + + +{% if user.is_authenticated and user.profile.show_ids %} + +{% endif %} + + + + + + + + + + + + + + + + +{% for series in page %} + +{% if user.is_authenticated and user.profile.show_ids %} + +{% endif %} + + + + + + + + +{% empty %} + + + +{% endfor %} + +
+ ID + + Series + + Version + + Cover Letter + + Patches + + {% if 'date.asc' == order %} + + + {% elif 'date.desc' == order %} + + + {% endif %} + Date + {% if 'date.asc' == order or 'date.desc' == order%} + + {% endif %} + + Submitter +
+ + + {{ series.name|default:"[no subject]"|truncatechars:100 }} + + {{ series.version|default:"-"}} + + {% if series.cover_letter.content %} + + {% else %} + - + {% endif %} + {{ series.received_total}}{{ series.date|date:"Y-m-d" }}{{ series.submitter|personify:project }}
No series to display
+ +{% if page.paginator.count %} +{% include "patchwork/partials/pagination.html" %} +{% endif %} +{% endblock %} diff --git a/patchwork/urls.py b/patchwork/urls.py index ecd3668de..15343ad0f 100644 --- a/patchwork/urls.py +++ b/patchwork/urls.py @@ -33,9 +33,19 @@ path('', project_views.project_list, name='project-list'), path( 'project//list/', + patch_views.patch_list_redirect, + name='patch-list-redirect', + ), + path( + 'project//patches/', patch_views.patch_list, name='patch-list', ), + path( + 'project//series/', + series_views.series_list, + name='series-list', + ), path( 'project//bundles/', bundle_views.bundle_list, diff --git a/patchwork/views/patch.py b/patchwork/views/patch.py index efe94f17c..198b26ca7 100644 --- a/patchwork/views/patch.py +++ b/patchwork/views/patch.py @@ -10,6 +10,7 @@ from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.shortcuts import render +from django.shortcuts import redirect from django.urls import reverse from patchwork.forms import CreateBundleForm @@ -38,6 +39,11 @@ def patch_list(request, project_id): return render(request, 'patchwork/list.html', context) +def patch_list_redirect(request, project_id): + new_url = reverse('patch-list', kwargs={'project_id': project_id}) + return redirect(f'{new_url}?{request.GET.urlencode()}') + + def patch_detail(request, project_id, msgid): project = get_object_or_404(Project, linkname=project_id) db_msgid = Patch.decode_msgid(msgid) diff --git a/patchwork/views/series.py b/patchwork/views/series.py index a8892ae6a..7c45fb741 100644 --- a/patchwork/views/series.py +++ b/patchwork/views/series.py @@ -2,12 +2,16 @@ # Copyright (C) 2017 Stephen Finucane # # SPDX-License-Identifier: GPL-2.0-or-later +import collections from django.http import HttpResponse from django.shortcuts import get_object_or_404 +from django.shortcuts import render from patchwork.models import Series +from patchwork.models import Project from patchwork.views.utils import series_to_mbox +from patchwork.paginator import Paginator def series_mbox(request, series_id): @@ -20,3 +24,43 @@ def series_mbox(request, series_id): ) return response + + +def series_list(request, project_id): + project = get_object_or_404(Project, linkname=project_id) + sort = request.GET.get('order', 'date.desc') + sort_field, sort_dir = sort.split('.') + sort_order = f"{'-' if sort_dir == 'desc' else ''}{sort_field}" + context = {} + series_list = ( + Series.objects.filter(project=project) + .only( + 'submitter', + 'project', + 'version', + 'name', + 'date', + 'id', + 'cover_letter', + ) + .select_related('project', 'submitter', 'cover_letter') + .order_by(sort_order) + ) + + paginator = Paginator(request, series_list) + context.update( + { + 'project': project, + 'projects': Project.objects.all(), + 'series_list': series_list, + 'page': paginator.current_page, + 'order': sort, + 'list_view': { + 'view': 'series-list', + 'view_params': {'project_id': project.linkname}, + 'params': collections.OrderedDict(), + }, + } + ) + + return render(request, 'patchwork/series-list.html', context) From 4770c98511503e0825b29d0c93b14fdb6ab09f45 Mon Sep 17 00:00:00 2001 From: andrepapoti Date: Mon, 22 Apr 2024 15:26:04 -0300 Subject: [PATCH 2/8] tests: Add tests for series list view Signed-off-by: andrepapoti --- patchwork/tests/views/test_series.py | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 patchwork/tests/views/test_series.py diff --git a/patchwork/tests/views/test_series.py b/patchwork/tests/views/test_series.py new file mode 100644 index 000000000..c37a98df0 --- /dev/null +++ b/patchwork/tests/views/test_series.py @@ -0,0 +1,51 @@ +# Patchwork - automated patch tracking system +# Copyright (C) 2024 Meta Platforms, Inc. and affiliates. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from datetime import datetime as dt + +from django.test import TestCase +from django.urls import reverse + +from patchwork.models import Person +from patchwork.tests.utils import create_patch +from patchwork.tests.utils import create_cover +from patchwork.tests.utils import create_person +from patchwork.tests.utils import create_project +from patchwork.tests.utils import create_series +from patchwork.tests.utils import create_user + + +class SeriesList(TestCase): + def setUp(self): + self.project = create_project() + self.user = create_user() + self.person_1 = Person.objects.get(user=self.user) + self.person_2 = create_person() + self.series_1 = create_series(project=self.project) + self.series_2 = create_series(project=self.project) + create_cover(project=self.project, series=self.series_1) + + for i in range(5): + create_patch( + submitter=self.person_1, + project=self.project, + series=self.series_1, + date=dt(2014, 3, 16, 13, 4, 50, 155643), + ) + create_patch( + submitter=self.person_2, + project=self.project, + series=self.series_2, + date=dt(2014, 3, 16, 13, 4, 50, 155643), + ) + + def test_series_list(self): + requested_url = reverse( + 'series-list', + kwargs={'project_id': self.project.linkname}, + ) + response = self.client.get(requested_url) + + self.assertEqual(response.status_code, 200) From 8659befffa1d399984823ab138f65cb13ae73773 Mon Sep 17 00:00:00 2001 From: andrepapoti Date: Tue, 23 Apr 2024 02:28:28 -0300 Subject: [PATCH 3/8] views: add series-detail view Signed-off-by: andrepapoti --- .../templates/patchwork/series-detail.html | 41 +++++++++++++++++++ .../templates/patchwork/series-list.html | 2 + patchwork/urls.py | 5 +++ patchwork/views/series.py | 23 +++++++++++ 4 files changed, 71 insertions(+) create mode 100644 patchwork/templates/patchwork/series-detail.html diff --git a/patchwork/templates/patchwork/series-detail.html b/patchwork/templates/patchwork/series-detail.html new file mode 100644 index 000000000..d38d7b9f9 --- /dev/null +++ b/patchwork/templates/patchwork/series-detail.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} + +{% load humanize %} +{% load syntax %} +{% load person %} +{% load patch %} +{% load static %} +{% load utils %} + +{% block title %}{{series.name}}{% endblock %} + +{% block body %} + +
+

{{ series.name }}

+
+ + + + + + + + + + + + + + + + + + +
Cover Letter{{ series.cover_letter.content|default:"No cover letter available" }}
Date{{ series.date }}
Submitter{{ series.submitter }}
Total{{ series.patches }}
+
+

Patches

+
+{% include "patchwork/partials/patch-list.html" %} + +{% endblock %} diff --git a/patchwork/templates/patchwork/series-list.html b/patchwork/templates/patchwork/series-list.html index f157c6ca2..bd23c252d 100644 --- a/patchwork/templates/patchwork/series-list.html +++ b/patchwork/templates/patchwork/series-list.html @@ -75,7 +75,9 @@ {% endif %} + {{ series.name|default:"[no subject]"|truncatechars:100 }} + {{ series.version|default:"-"}} diff --git a/patchwork/urls.py b/patchwork/urls.py index 15343ad0f..63a2a0e2d 100644 --- a/patchwork/urls.py +++ b/patchwork/urls.py @@ -120,6 +120,11 @@ name='comment-redirect', ), # series views + path( + 'project//series//', + series_views.series_detail, + name='series-detail', + ), path( 'series//mbox/', series_views.series_mbox, diff --git a/patchwork/views/series.py b/patchwork/views/series.py index 7c45fb741..a36b80412 100644 --- a/patchwork/views/series.py +++ b/patchwork/views/series.py @@ -9,7 +9,9 @@ from django.shortcuts import render from patchwork.models import Series +from patchwork.models import Patch from patchwork.models import Project +from patchwork.views import generic_list from patchwork.views.utils import series_to_mbox from patchwork.paginator import Paginator @@ -26,6 +28,27 @@ def series_mbox(request, series_id): return response +def series_detail(request, project_id, series_id): + series = get_object_or_404(Series, id=series_id) + + patches = Patch.objects.filter(series=series) + + context = generic_list( + request, + series.project, + 'series-detail', + view_args={ + 'project_id': project_id, + 'series_id': series_id, + }, + patches=patches, + ) + + context.update({'series': series}) + + return render(request, 'patchwork/series-detail.html', context) + + def series_list(request, project_id): project = get_object_or_404(Project, linkname=project_id) sort = request.GET.get('order', 'date.desc') From ca73edf226e6fb6dd6f1feac696b76f41867054a Mon Sep 17 00:00:00 2001 From: Andre Papoti Date: Tue, 24 Dec 2024 17:18:39 -0300 Subject: [PATCH 4/8] views: add shortcut to series-list view on navigation bar --- templates/base.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/templates/base.html b/templates/base.html index 9519ecc55..49663d7f1 100644 --- a/templates/base.html +++ b/templates/base.html @@ -48,6 +48,12 @@ {% block navbarmenu %} {% if project %}