From patchwork Mon Aug 23 18:28:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raxel Gutierrez X-Patchwork-Id: 1519909 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=sIRbWXWE; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Gtgk46Zzqz9sWX for ; Tue, 24 Aug 2021 04:29:00 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4Gtgk42lpqz2xtf for ; Tue, 24 Aug 2021 04:29:00 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=sIRbWXWE; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=flex--raxel.bounces.google.com (client-ip=2607:f8b0:4864:20::b4a; helo=mail-yb1-xb4a.google.com; envelope-from=32ugjyqukcus4naryt11tyr.p1z2n6pu914xyv565.1cyno5.14t@flex--raxel.bounces.google.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=sIRbWXWE; dkim-atps=neutral Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Gtgjp5PT5z2xfJ for ; Tue, 24 Aug 2021 04:28:44 +1000 (AEST) Received: by mail-yb1-xb4a.google.com with SMTP id z2-20020a5b0b02000000b005982be23a34so10745080ybp.19 for ; Mon, 23 Aug 2021 11:28:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=rhGYgQ+1dbN4kD15eGE1td8rLlejAxVft0uKOsvl3o8=; b=sIRbWXWECzyscFD7McEgO7B7TVM/wODdaeX0B35TJZyFJooPgQX7osvMEK76cF4P9I enIE5iFjDxDMa1wzBGoMDmsso8/PwodJmBBmlXy52YJjQFVN3xZ+T8qUKrc0EidNVtIU hVcLAx2AESCPaio9wkwAFAhpnfYTHrGxW+j27KLy58fBOFeVTOq1svrIlYPkt/V4T72P lqNuRT/bOk1oLsvkZJjozUc3jlnFrLRNzrSOdQS1dT9d5ShRWPSNp7WoBK5htgMZ9ock GWPOkJd/+fAPNlxJFm7YyvVQFc20Mi3/54mmhfoKUeQyaajOmVf0RvVV+if/NKk9XUMa qdBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=rhGYgQ+1dbN4kD15eGE1td8rLlejAxVft0uKOsvl3o8=; b=s/I6dyAOxlTa/A55tNPecPfn8SuSgewWG3d54ndoFoxMCTAeV1vlye4kQmysZ2pvXd 42PqK91aCTBT01ljUTOj7Nd/Lxn+HoGZ3aV/s45nJmXVMgnmA3HZEZmZ61RI4iqv7Cqb h7jfBlEerI2GHFNXWTChP+HYwB41c23rDvNqpJ8d+cKoGFKuQ+CQFu80+gp26w6ZgXev bRpqltymIkWXSzvU9DuWnGU+BknxsGT8wWVp9njGtPNziFBCtUWAXRi3gzVTyiKEBdIl d7rZuEjNDhvsws71ABpc9UV93T4gZ0n9V92Xz3jKrKUQI3JSOJAi6Ij9FpU8hDkC5fq6 K4Xw== X-Gm-Message-State: AOAM533uwHRpPj65giPiq5sfZBa4BPySKUvtuWW2IYXE8EymmMJPDYYk 3ktmaQdkYHaIlI16Y2R/sWLFgvrXEJqVX9ODhAIB1DDqXCw5fC3KUmSB/GXZNTEXuFvJdyei+MH A4vDJs11ywcQ/RRVhh8JXUo1eWm8vXdCVm09VIyDEvEf3AVeQV0VK1mto6PJC25rs X-Google-Smtp-Source: ABdhPJwNEScLvB7gkOLLz7rQlDyqFVZJq1T0D79AjjUI7AdwlRUrxNBdHVCZ5ySaMJLUL3lw3aPuj13zSw== X-Received: from raxel-pw.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2fda]) (user=raxel job=sendgmr) by 2002:a25:818a:: with SMTP id p10mr43864493ybk.363.1629743322080; Mon, 23 Aug 2021 11:28:42 -0700 (PDT) Date: Mon, 23 Aug 2021 18:28:29 +0000 In-Reply-To: <20210823182833.3976100-1-raxel@google.com> Message-Id: <20210823182833.3976100-2-raxel@google.com> Mime-Version: 1.0 References: <20210823182833.3976100-1-raxel@google.com> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog Subject: [PATCH v4 1/5] patch-list: clean up patch-list page From: Raxel Gutierrez To: patchwork@lists.ozlabs.org X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Add ids to table cells, and rename selectors using hyphen delimited strings to clean up and improve readability of patch-list.html. Also, create a partial template errors.html for errors that render with form submission.These changes make the code healthier, ready for change, and overall more readable. No user-visible change should be noticed. Signed-off-by: Raxel Gutierrez --- htdocs/css/style.css | 16 ++-- htdocs/js/bundle.js | 12 +-- .../patchwork/partials/patch-list.html | 84 +++++++++---------- patchwork/templates/patchwork/submission.html | 6 +- patchwork/tests/views/test_bundles.py | 20 ++--- patchwork/tests/views/test_patch.py | 6 +- patchwork/views/__init__.py | 4 +- patchwork/views/bundle.py | 2 +- 8 files changed, 75 insertions(+), 75 deletions(-) diff --git a/htdocs/css/style.css b/htdocs/css/style.css index 9156aa6e..4ad503da 100644 --- a/htdocs/css/style.css +++ b/htdocs/css/style.css @@ -134,25 +134,25 @@ table.pw-list > thead { background-color: white; } -a.colinactive, a.colactive { +a.col-inactive, a.col-active { color: black; text-decoration: none; } -a.colinactive:hover { +a.col-inactive:hover { color: red; } div.filters { } -div.patchforms { +div.patch-forms { margin-top: 1em; } /* list order manipulation */ -table.patchlist tr.draghover { +table.patch-list tr.draghover { background: #e8e8e8 !important; } @@ -228,7 +228,7 @@ table.patch-meta tr th, table.patch-meta tr td { } /* checks forms */ -/* TODO(stephenfin): Merge this with 'div.patchform' rules */ +/* TODO(stephenfin): Merge this with 'div.patch-form' rules */ .checks { border: 1px solid gray; margin: 0.5em 1em; @@ -406,7 +406,7 @@ table.bundlelist td } /* forms that appear for a patch */ -div.patchform { +div.patch-form { border: thin solid #080808; padding-left: 0.6em; padding-right: 0.6em; @@ -414,7 +414,7 @@ div.patchform { margin: 0.5em 5em 0.5em 10px; } -div.patchform h3 { +div.patch-form h3 { margin-top: 0em; margin-left: -0.6em; margin-right: -0.6em; @@ -424,7 +424,7 @@ div.patchform h3 { font-size: 100%; } -div.patchform ul { +div.patch-form ul { list-style-type: none; padding-left: 0.2em; margin-top: 0em; diff --git a/htdocs/js/bundle.js b/htdocs/js/bundle.js index c969d0be..2a721d0d 100644 --- a/htdocs/js/bundle.js +++ b/htdocs/js/bundle.js @@ -6,8 +6,8 @@ function order_button_click(node) { var rows, form; - form = $("#reorderform"); - rows = $("#patchlist").get(0).tBodies[0].rows; + form = $("#reorder-form"); + rows = $("#patch-list").get(0).tBodies[0].rows; if (rows.length < 1) return; @@ -35,18 +35,18 @@ function order_button_click(node) $("#reorder\\-cancel").css("display", "inline"); /* show help text */ - $("#reorderhelp").text('Drag & drop rows to reorder'); + $("#reorder-help").text('Drag & drop rows to reorder'); /* enable drag & drop on the patches list */ - $("#patchlist").tableDnD({ + $("#patch-list").tableDnD({ onDragClass: 'dragging', onDragStart: function() { dragging = true; }, onDrop: function() { dragging = false; } }); /* replace zebra striping with hover */ - $("#patchlist tbody tr").css("background", "inherit"); - $("#patchlist tbody tr").hover(drag_hover_in, drag_hover_out); + $("#patch-list tbody tr").css("background", "inherit"); + $("#patch-list tbody tr").hover(drag_hover_in, drag_hover_out); } editing_order = !editing_order; diff --git a/patchwork/templates/patchwork/partials/patch-list.html b/patchwork/templates/patchwork/partials/patch-list.html index 02d6dff8..80ae6908 100644 --- a/patchwork/templates/patchwork/partials/patch-list.html +++ b/patchwork/templates/patchwork/partials/patch-list.html @@ -9,14 +9,14 @@ {% include "patchwork/partials/pagination.html" %} {% if order.editable %} - +
- - - + + {% empty %} diff --git a/patchwork/views/__init__.py b/patchwork/views/__init__.py index 5da8046d..d41c4609 100644 --- a/patchwork/views/__init__.py +++ b/patchwork/views/__init__.py @@ -16,6 +16,7 @@ from patchwork.models import Bundle from patchwork.models import BundlePatch from patchwork.models import Patch from patchwork.models import Project +from patchwork.models import State from patchwork.models import Check from patchwork.paginator import Paginator @@ -177,6 +178,8 @@ def generic_list(request, project, view, view_args=None, filter_settings=None, 'project': project, 'projects': Project.objects.all(), 'filters': filters, + 'maintainers': project.maintainer_project.all(), + 'states': State.objects.all(), } # pagination @@ -287,6 +290,9 @@ def generic_list(request, project, view, view_args=None, filter_settings=None, Prefetch('check_set', queryset=Check.objects.only( 'context', 'user_id', 'patch_id', 'state', 'date'))) + for patch in patches: + patch.is_editable = patch.is_editable(user) + paginator = Paginator(request, patches) context.update({
-
+
+ {% csrf_token %} - + - + - + @@ -52,9 +52,9 @@ $(document).ready(function() { {% csrf_token %} - + - @@ -72,23 +72,23 @@ $(document).ready(function() { @@ -174,9 +174,9 @@ $(document).ready(function() { {% for patch in page.object_list %} - + {% if user.is_authenticated %} - {% endif %} @@ -188,24 +188,24 @@ $(document).ready(function() { {% endif %} - - - - - - - - + + + + + + {% empty %} @@ -218,10 +218,10 @@ $(document).ready(function() { {% if page.paginator.count %} {% include "patchwork/partials/pagination.html" %} -
+
{% if patchform %} -
+

Properties

{% if order.name == "name" %} - + - + Patch {% else %} {% if not order.editable %} - Patch + Patch {% else %} - Patch + Patch {% endif %} {% endif %} - Series + Series @@ -101,70 +101,70 @@ $(document).ready(function() { {% if order.name == "date" %} - + - + Date {% else %} {% if not order.editable %} - Date + Date {% else %} - Date + Date {% endif %} {% endif %} {% if order.name == "submitter" %} - + - + Submitter {% else %} {% if not order.editable %} - + Submitter {% else %} - Submitter + Submitter {% endif %} {% endif %} {% if order.name == "delegate" %} - + - + Delegate {% else %} {% if not order.editable %} - Delegate + Delegate {% else %} - Delegate + Delegate {% endif %} {% endif %} {% if order.name == "state" %} - + - + State {% else %} {% if not order.editable %} - State + State {% else %} - State + State {% endif %} {% endif %}
+ + {{ patch.name|default:"[no subject]"|truncatechars:100 }} + {% if patch.series %} {{ patch.series|truncatechars:100 }} {% endif %} {{ patch|patch_tags }}{{ patch|patch_checks }}{{ patch.date|date:"Y-m-d" }}{{ patch.submitter|personify:project }}{{ patch.delegate.username }}{{ patch.state }}{{ patch|patch_tags }}{{ patch|patch_checks }}{{ patch.date|date:"Y-m-d" }}{{ patch.submitter|personify:project }}{{ patch.delegate.username }}{{ patch.state }}
@@ -257,7 +257,7 @@ $(document).ready(function() { {% endif %} {% if user.is_authenticated %} -
+

Bundling

diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html index 2238e82e..b617d366 100644 --- a/patchwork/templates/patchwork/submission.html +++ b/patchwork/templates/patchwork/submission.html @@ -135,9 +135,9 @@ {% endif %}
-
+
{% if patchform %} -
+

Patch Properties

{% csrf_token %} @@ -175,7 +175,7 @@ {% endif %} {% if createbundleform %} -
+

Bundling

diff --git a/patchwork/tests/views/test_bundles.py b/patchwork/tests/views/test_bundles.py index 6a744093..e265eb69 100644 --- a/patchwork/tests/views/test_bundles.py +++ b/patchwork/tests/views/test_bundles.py @@ -353,7 +353,7 @@ class BundleCreateFromListTest(BundleTestBase): def test_create_empty_bundle(self): newbundlename = 'testbundle-new' - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'bundle_name': newbundlename, 'action': 'Create', 'project': self.project.id} @@ -369,7 +369,7 @@ class BundleCreateFromListTest(BundleTestBase): newbundlename = 'testbundle-new' patch = self.patches[0] - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'bundle_name': newbundlename, 'action': 'Create', 'project': self.project.id, @@ -393,7 +393,7 @@ class BundleCreateFromListTest(BundleTestBase): n_bundles = Bundle.objects.count() - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'bundle_name': '', 'action': 'Create', 'project': self.project.id, @@ -414,7 +414,7 @@ class BundleCreateFromListTest(BundleTestBase): newbundlename = 'testbundle-dup' patch = self.patches[0] - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'bundle_name': newbundlename, 'action': 'Create', 'project': self.project.id, @@ -489,7 +489,7 @@ class BundleAddFromListTest(BundleTestBase): def test_add_to_empty_bundle(self): patch = self.patches[0] - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'action': 'Add', 'project': self.project.id, 'bundle_id': self.bundle.id, @@ -509,7 +509,7 @@ class BundleAddFromListTest(BundleTestBase): def test_add_to_non_empty_bundle(self): self.bundle.append_patch(self.patches[0]) patch = self.patches[1] - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'action': 'Add', 'project': self.project.id, 'bundle_id': self.bundle.id, @@ -538,7 +538,7 @@ class BundleAddFromListTest(BundleTestBase): count = self.bundle.patches.count() patch = self.patches[0] - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'action': 'Add', 'project': self.project.id, 'bundle_id': self.bundle.id, @@ -559,7 +559,7 @@ class BundleAddFromListTest(BundleTestBase): count = self.bundle.patches.count() patch = self.patches[0] - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'action': 'Add', 'project': self.project.id, 'bundle_id': self.bundle.id, @@ -650,7 +650,7 @@ class BundleInitialOrderTest(BundleTestBase): newbundlename = 'testbundle-new' # need to define our querystring explicity to enforce ordering - params = {'form': 'patchlistform', + params = {'form': 'patch-list-form', 'bundle_name': newbundlename, 'action': 'Create', 'project': self.project.id, @@ -704,7 +704,7 @@ class BundleReorderTest(BundleTestBase): patch=self.patches[start]).patch slice_ids = neworder_ids[start:end] - params = {'form': 'reorderform', + params = {'form': 'reorder-form', 'order_start': firstpatch.id, 'neworder': slice_ids} diff --git a/patchwork/tests/views/test_patch.py b/patchwork/tests/views/test_patch.py index 1a1243cf..22ee0c19 100644 --- a/patchwork/tests/views/test_patch.py +++ b/patchwork/tests/views/test_patch.py @@ -71,7 +71,7 @@ class PatchListOrderingTest(TestCase): date=date) def _extract_patch_ids(self, response): - id_re = re.compile(r' X-Patchwork-Id: 1519910 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=ZU/k+SQo; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GtgkB4kl4z9sWS for ; Tue, 24 Aug 2021 04:29:06 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4GtgkB3GVnz2yJn for ; Tue, 24 Aug 2021 04:29:06 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=ZU/k+SQo; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=flex--raxel.bounces.google.com (client-ip=2607:f8b0:4864:20::f49; helo=mail-qv1-xf49.google.com; envelope-from=32-gjyqukcuw5obszu22uzs.q203o7qva25yzw676.2dzop6.25u@flex--raxel.bounces.google.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=ZU/k+SQo; dkim-atps=neutral Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Gtgjp5dHmz2xh0 for ; Tue, 24 Aug 2021 04:28:45 +1000 (AEST) Received: by mail-qv1-xf49.google.com with SMTP id e17-20020a0562141511b029034f8146604fso13025285qvy.12 for ; Mon, 23 Aug 2021 11:28:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7/RIMUV5VIkcE6gtfVzpMHxGvaM2aQLB83cSWuAYvjo=; b=ZU/k+SQodkYCs/XT4gO/f02vFCNwNhpgeir0s7B0tUTYk3zb1otrWpv231F16uc9d8 guWW/wdg+ADFLc1vl2mbQuSVjaQLjSp0AnkVnQvfXZ980BmNQoz9oTTmwVwaGn7FHIAU 0te7EC2IMQyXWLztEwflBMPrY+3eT2cOGxfh8BxUsg91PLXMB3q6sp/GOmFj7t39SXUH AHzPVsGBMaDkIZnBQuCwve7nz+c62fkiOEGgALdvzYyNFcUwqaqr5+wRXWV73ELse+gb nWhE/FIcjgQvPhbDOOv1e2SKagqd46kkGaxgss9BfOk9z+QiC0dVRZ/8Wge26XVlDnAV 7OjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7/RIMUV5VIkcE6gtfVzpMHxGvaM2aQLB83cSWuAYvjo=; b=RjWPrOXfipYrnYW3esajYae9ZvXulclAhhYdScZ7UiYXQMR2KZ84dCnGTa9+DkH94E OdsXoPaZx9PiQ1nyv/9z6Rt5WBu9Ey/b7SvrIhk1dFDtV+WEmgxMqdfe5yA5H23EuqQ2 A5F1/IRclJfODzEg/3HiyPnO3HGFpH1XUG4cwSTpUmJVIjNJA24RfTyVz28l8DWnx4t0 w+MFP+46wh/PeKcjt+rE1dfepTc62GjaO3nJjB8r350KKQJCkWa0c1F8ABr/99eYdfSX GOiZgkzrj0+vnb4TXfQWclFld+CBKXfqaQdoBc8bU2Ud9LfVDVbMpzBlrt79MFwnlMAG k5jA== X-Gm-Message-State: AOAM533VRNnqA2Z9H5WJO0vJG72qMzT1EITmNiO2Ew0liigLV6khfTdc bE11Xwb3SGXgZ2/4cbK2SVBS6be3ReOr8aUu6hrNHiMPwh4mCcsyYQIJba3ezPDH0SI4VxBdMe3 iVshaXc5avvAA+9OJ059Thpj9KI8MRaE3fJrX92Rhg9KG5nlogU7BWzt17sVg/TyK X-Google-Smtp-Source: ABdhPJz4lZ70BEJF3DO1GI1kG3rXTaSzF4GxA0O5BnGdh2wvMunhW8ki7TrhXokQhttOMsqXC/D0qDAIKQ== X-Received: from raxel-pw.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2fda]) (user=raxel job=sendgmr) by 2002:a05:6214:15c1:: with SMTP id p1mr35367222qvz.9.1629743323596; Mon, 23 Aug 2021 11:28:43 -0700 (PDT) Date: Mon, 23 Aug 2021 18:28:30 +0000 In-Reply-To: <20210823182833.3976100-1-raxel@google.com> Message-Id: <20210823182833.3976100-3-raxel@google.com> Mime-Version: 1.0 References: <20210823182833.3976100-1-raxel@google.com> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog Subject: [PATCH v4 2/5] patch-list: move js code to separate file From: Raxel Gutierrez To: patchwork@lists.ozlabs.org X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Move patch-list related JS code to a new patch-list.js file, to make the JavaScript easy to read and change in one place. This makes automatic code formatting easier, makes it more straightforward to measure test coverage and discover opportunities for refactoring, and simplifies a possible future migration to TypeScript if the project chooses to go in that direction. No user-visible change should be noticed. Signed-off-by: Raxel Gutierrez --- htdocs/README.rst | 6 ++++++ htdocs/js/patch-list.js | 12 ++++++++++++ .../patchwork/partials/patch-list.html | 19 ++++--------------- 3 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 htdocs/js/patch-list.js diff --git a/htdocs/README.rst b/htdocs/README.rst index d53619ad..6c435124 100644 --- a/htdocs/README.rst +++ b/htdocs/README.rst @@ -122,6 +122,12 @@ js :GitHub: https://github.com/js-cookie/js-cookie/ :Version: 3.0.0 +``patch-list.js.`` + Event helpers and other application logic for patch-list.html. These + support patch list manipulation. + + Part of Patchwork. + ``rest.js.`` Utility module for REST API requests to be used by other Patchwork JS files. diff --git a/htdocs/js/patch-list.js b/htdocs/js/patch-list.js new file mode 100644 index 00000000..6ae13721 --- /dev/null +++ b/htdocs/js/patch-list.js @@ -0,0 +1,12 @@ +$( document ).ready(function() { + $("#patch-list").stickyTableHeaders(); + + $("#check-all").change(function(e) { + if(this.checked) { + $("#patch-list > tbody").checkboxes("check"); + } else { + $("#patch-list > tbody").checkboxes("uncheck"); + } + e.preventDefault(); + }); +}); \ No newline at end of file diff --git a/patchwork/templates/patchwork/partials/patch-list.html b/patchwork/templates/patchwork/partials/patch-list.html index 80ae6908..19b019cd 100644 --- a/patchwork/templates/patchwork/partials/patch-list.html +++ b/patchwork/templates/patchwork/partials/patch-list.html @@ -4,6 +4,10 @@ {% load project %} {% load static %} +{% block headers %} + +{% endblock %} + {% include "patchwork/partials/filters.html" %} {% include "patchwork/partials/pagination.html" %} @@ -35,21 +39,6 @@ {% endif %} - - {% csrf_token %} From patchwork Mon Aug 23 18:28:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raxel Gutierrez X-Patchwork-Id: 1519911 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=i17BHKGN; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GtgkJ5RLRz9sWS for ; Tue, 24 Aug 2021 04:29:12 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4GtgkJ400cz2xtW for ; Tue, 24 Aug 2021 04:29:12 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=i17BHKGN; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=flex--raxel.bounces.google.com (client-ip=2607:f8b0:4864:20::f49; helo=mail-qv1-xf49.google.com; envelope-from=33egjyqukcu47qdu1w44w1u.s425q9sxc4701y898.4f1qr8.47w@flex--raxel.bounces.google.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=i17BHKGN; dkim-atps=neutral Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Gtgjq5Yf6z2xfx for ; Tue, 24 Aug 2021 04:28:47 +1000 (AEST) Received: by mail-qv1-xf49.google.com with SMTP id q13-20020a0ce9cd000000b003608f06491fso13008793qvo.18 for ; Mon, 23 Aug 2021 11:28:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ZhsqsKzk0zVCJnE28+BrgIf/aLuN4mRPlo3JbqU1Sss=; b=i17BHKGNDrL4Jr37yCjynSODnyn6UIaKgIUZL9JT5YFpjhZdGso8UZqv/no/LkvPUK fWSBbZ5EoWE2CJVmnLxN6HREdCYtUe9/ZJbT/qhiLtJXMcDCDlIeCN27xQkRV4bUiJsn OJD75ANhhqgEsDBnEyY85VVuFbLBqoL9ibU2L47eI2AM2zuRXfKBN9JRo2I8pYWXuad9 0dXFwjHfXaKbJnEDU5HnGYbvZz1L8DtVHf95mWniuLtAVahE9r6x4/rFixhxE/MydoPu +oN5Pj65Z0DfLEpirVgagHWPPnTT+3QjcdmLKNdyDz11kBzz/QNrvlZ4uR0PyoI1mb4a rLgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZhsqsKzk0zVCJnE28+BrgIf/aLuN4mRPlo3JbqU1Sss=; b=hWpNcL1Keb0Oaa+6OmaRQL3T8JFb6i3JwdYPrlRxbboO1rvrGsE7D/zFXP6gW0LKhT zbGfqzqORIE9fPczXE+mUhMMwiv6YWIGyHOFu376GRtqFJdhmQZaiii34jyk8Kn5OkOO Db68FPzZPYuRJHIBjd+KJiG/XhH6BJU3f9cc8w3+yW9TTwd3/ZJwhQlyD1w/1a/UETHr qzaoWYI4Wn2bKko2lre67MrncHhZ8lTLyFIY5UjILi6IHd8VS63QvYaKQWh2Q/9q/2fQ bYCVF5zuOsKHu6bP3oPKZ0SLwkCMNJ9Zpk6PKs6J4XTyZDXGJCAIZ4S8tqWY0vy5GBq7 KgwQ== X-Gm-Message-State: AOAM532KKbd68IPZ/agyVqrVd4w2ssKTClvIk9l4NtTlPTslj5bE+PUn CpyNbLocveXPsvW8Ao0dUKLCTUVQ9hK6+niW0YkU65dBTHOH5IeUpaZbWa40mD3QH72dwiE1LGJ YkOnQeNIPJIc35PAKI0HcpLeHvcLYcXdCfG6qTJh31xplUkGIXGZSiCZDjiwSbJNp X-Google-Smtp-Source: ABdhPJzdEtdi9FVmpdhc7CA7giG2KfPqEp6ONlCfmJxBdi/cco/uw5cOdupQeSaxGBP6V0cPg2scTeepJg== X-Received: from raxel-pw.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2fda]) (user=raxel job=sendgmr) by 2002:ad4:51ca:: with SMTP id p10mr3857446qvq.27.1629743325299; Mon, 23 Aug 2021 11:28:45 -0700 (PDT) Date: Mon, 23 Aug 2021 18:28:31 +0000 In-Reply-To: <20210823182833.3976100-1-raxel@google.com> Message-Id: <20210823182833.3976100-4-raxel@google.com> Mime-Version: 1.0 References: <20210823182833.3976100-1-raxel@google.com> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog Subject: [PATCH v4 3/5] patch-list: move and refactor patch-forms From: Raxel Gutierrez To: patchwork@lists.ozlabs.org X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Move patch forms in patch-list and detail page to a new template file patch-forms.html and move them to the top of the patch-list page to improve their discoverability. Refactor forms.py, __init__.py, patch.py, and test_bundles.py files so that the shared bundle form in patch-forms.html works for both the patch-list and patch-detail pages. In particular, the changes normalize the behavior of the error and update messages of the patch forms and updates tests to reflect the changes. Overall, these changes make patch forms ready for change and more synchronized in their behavior. More specifically: - Previously patch forms changes were separated between the patch-detail and patch-list pages. Thus, desired changes to the patch forms required changes to patch-list.html, submission.html, and forms.py. So, the most important benefit to this change is that forms.py and patch-forms.html become the two places to adjust the forms to handle form validation and functionality as well as UI changes. - Previously the patch forms in patch-list.html handled error and update messages through views in patch.py, whereas the patch forms in submission.html handled the messages with forms.py. Now, with a single patch forms component in patch-forms.html, forms.py is set to handle the messages and handle form validation for both pages. Signed-off-by: Raxel Gutierrez --- patchwork/forms.py | 12 ++- .../patchwork/partials/patch-forms.html | 45 ++++++++ .../patchwork/partials/patch-list.html | 100 ++---------------- patchwork/templates/patchwork/submission.html | 89 +--------------- patchwork/tests/views/test_bundles.py | 26 ++--- patchwork/views/__init__.py | 71 +++++++------ patchwork/views/patch.py | 35 ++---- 7 files changed, 126 insertions(+), 252 deletions(-) create mode 100644 patchwork/templates/patchwork/partials/patch-forms.html diff --git a/patchwork/forms.py b/patchwork/forms.py index 24322c78..33103f4d 100644 --- a/patchwork/forms.py +++ b/patchwork/forms.py @@ -6,6 +6,7 @@ from django.contrib.auth.models import User from django import forms from django.db.models import Q +from django.core.exceptions import ValidationError from django.db.utils import ProgrammingError from patchwork.models import Bundle @@ -51,7 +52,7 @@ class EmailForm(forms.Form): class BundleForm(forms.ModelForm): name = forms.RegexField( - regex=r'^[^/]+$', min_length=1, max_length=50, label=u'Name', + regex=r'^[^/]+$', min_length=1, max_length=50, required=False, error_messages={'invalid': 'Bundle names can\'t contain slashes'}) class Meta: @@ -70,11 +71,16 @@ class CreateBundleForm(BundleForm): def clean_name(self): name = self.cleaned_data['name'] + if not name: + raise ValidationError('No bundle name was specified', + code="invalid") + count = Bundle.objects.filter(owner=self.instance.owner, name=name).count() if count > 0: - raise forms.ValidationError('A bundle called %s already exists' - % name) + raise ValidationError('A bundle called %(name)s already exists', + code="invalid", + params={'name': name}) return name diff --git a/patchwork/templates/patchwork/partials/patch-forms.html b/patchwork/templates/patchwork/partials/patch-forms.html new file mode 100644 index 00000000..5a824aaf --- /dev/null +++ b/patchwork/templates/patchwork/partials/patch-forms.html @@ -0,0 +1,45 @@ +
+{% if patchform %} +
+
+ {{ patchform.state.errors }} + {{ patchform.state }} +
+
+ {{ patchform.delegate.errors }} + {{ patchform.delegate }} +
+
+ {{ patchform.archived.errors }} + {{ patchform.archived.label_tag }} {{ patchform.archived }} +
+ +
+{% endif %} +{% if user.is_authenticated %} +
+
+ {{ createbundleform.name.errors }} + {{ createbundleform.name }} + +
+ {% if bundles %} +
+ + +
+ {% endif %} + {% if bundle %} +
+ + +
+ {% endif %} +
+{% endif %} +
diff --git a/patchwork/templates/patchwork/partials/patch-list.html b/patchwork/templates/patchwork/partials/patch-list.html index 19b019cd..aeb26aa8 100644 --- a/patchwork/templates/patchwork/partials/patch-list.html +++ b/patchwork/templates/patchwork/partials/patch-list.html @@ -10,8 +10,6 @@ {% include "patchwork/partials/filters.html" %} -{% include "patchwork/partials/pagination.html" %} - {% if order.editable %}
@@ -31,19 +29,15 @@
{% endif %} -{% if page.paginator.long_page and user.is_authenticated %} - -{% endif %} - - + {% csrf_token %} - + {% include "patchwork/partials/patch-forms.html" %} + {% include "patchwork/partials/pagination.html" %} + +
@@ -163,7 +157,7 @@ {% for patch in page.object_list %} - + {% if user.is_authenticated %}
@@ -206,86 +200,6 @@ {% if page.paginator.count %} {% include "patchwork/partials/pagination.html" %} - -
- -{% if patchform %} -
-

Properties

- - - - - - - - - - - - - - - - - -
Change state: - {{ patchform.state }} - {{ patchform.state.errors }} -
Delegate to: - {{ patchform.delegate }} - {{ patchform.delegate.errors }} -
Archive: - {{ patchform.archived }} - {{ patchform.archived.errors }} -
- -
-
- -{% endif %} - -{% if user.is_authenticated %} -
-

Bundling

- - - - - - {% if bundles %} - - - - - {% endif %} - {% if bundle %} - - - - - {% endif %} -
Create bundle: - - -
Add to bundle: - - -
Remove from bundle: - - -
-
-{% endif %} - -
-
-
- {% endif %} diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html index b617d366..4b0e9601 100644 --- a/patchwork/templates/patchwork/submission.html +++ b/patchwork/templates/patchwork/submission.html @@ -135,91 +135,10 @@ {% endif %}
-
-{% if patchform %} -
-

Patch Properties

-
- {% csrf_token %} - - - - - - - - - - - - - - - - - -
Change state: - {{ patchform.state }} - {{ patchform.state.errors }} -
Delegate to: - {{ patchform.delegate }} - {{ patchform.delegate.errors }} -
Archived: - {{ patchform.archived }} - {{ patchform.archived.errors }} -
- -
-
-
-{% endif %} - -{% if createbundleform %} -
-

Bundling

- - - - - -{% if bundles %} - - - - -{% endif %} -
Create bundle: - {% if createbundleform.non_field_errors %} -
{{createbundleform.non_field_errors}}
- {% endif %} -
- {% csrf_token %} - - {% if createbundleform.name.errors %} -
{{createbundleform.name.errors}}
- {% endif %} - {{ createbundleform.name }} - -
-
Add to bundle: -
- {% csrf_token %} - - - -
-
- -
-{% endif %} - -
-
-
+
+ {% csrf_token %} + {% include "patchwork/partials/patch-forms.html" %} +
{% if submission.pull_url %}

Pull-request

diff --git a/patchwork/tests/views/test_bundles.py b/patchwork/tests/views/test_bundles.py index e265eb69..b9818f71 100644 --- a/patchwork/tests/views/test_bundles.py +++ b/patchwork/tests/views/test_bundles.py @@ -354,7 +354,7 @@ class BundleCreateFromListTest(BundleTestBase): def test_create_empty_bundle(self): newbundlename = 'testbundle-new' params = {'form': 'patch-list-form', - 'bundle_name': newbundlename, + 'name': newbundlename, 'action': 'Create', 'project': self.project.id} @@ -370,7 +370,7 @@ class BundleCreateFromListTest(BundleTestBase): patch = self.patches[0] params = {'form': 'patch-list-form', - 'bundle_name': newbundlename, + 'name': newbundlename, 'action': 'Create', 'project': self.project.id, 'patch_id:%d' % patch.id: 'checked'} @@ -394,7 +394,7 @@ class BundleCreateFromListTest(BundleTestBase): n_bundles = Bundle.objects.count() params = {'form': 'patch-list-form', - 'bundle_name': '', + 'name': '', 'action': 'Create', 'project': self.project.id, 'patch_id:%d' % patch.id: 'checked'} @@ -415,7 +415,7 @@ class BundleCreateFromListTest(BundleTestBase): patch = self.patches[0] params = {'form': 'patch-list-form', - 'bundle_name': newbundlename, + 'name': newbundlename, 'action': 'Create', 'project': self.project.id, 'patch_id:%d' % patch.id: 'checked'} @@ -440,7 +440,9 @@ class BundleCreateFromListTest(BundleTestBase): params) self.assertNotContains(response, 'Bundle %s created' % newbundlename) - self.assertContains(response, 'You already have a bundle called') + self.assertContains( + response, + 'A bundle called %s already exists' % newbundlename) self.assertEqual(Bundle.objects.count(), n_bundles) self.assertEqual(bundle.patches.count(), 1) @@ -452,7 +454,7 @@ class BundleCreateFromPatchTest(BundleTestBase): patch = self.patches[0] params = {'name': newbundlename, - 'action': 'createbundle'} + 'action': 'Create'} response = self.client.post( reverse('patch-detail', @@ -471,7 +473,7 @@ class BundleCreateFromPatchTest(BundleTestBase): patch = self.patches[0] params = {'name': newbundlename, - 'action': 'createbundle'} + 'action': 'Create'} response = self.client.post( reverse('patch-detail', @@ -584,7 +586,7 @@ class BundleAddFromPatchTest(BundleTestBase): def test_add_to_empty_bundle(self): patch = self.patches[0] - params = {'action': 'addtobundle', + params = {'action': 'Add', 'bundle_id': self.bundle.id} response = self.client.post( @@ -594,7 +596,7 @@ class BundleAddFromPatchTest(BundleTestBase): self.assertContains( response, - 'added to bundle "%s"' % self.bundle.name, + 'added to bundle %s' % self.bundle.name, count=1) self.assertEqual(self.bundle.patches.count(), 1) @@ -603,7 +605,7 @@ class BundleAddFromPatchTest(BundleTestBase): def test_add_to_non_empty_bundle(self): self.bundle.append_patch(self.patches[0]) patch = self.patches[1] - params = {'action': 'addtobundle', + params = {'action': 'Add', 'bundle_id': self.bundle.id} response = self.client.post( @@ -613,7 +615,7 @@ class BundleAddFromPatchTest(BundleTestBase): self.assertContains( response, - 'added to bundle "%s"' % self.bundle.name, + 'added to bundle %s' % self.bundle.name, count=1) self.assertEqual(self.bundle.patches.count(), 2) @@ -651,7 +653,7 @@ class BundleInitialOrderTest(BundleTestBase): # need to define our querystring explicity to enforce ordering params = {'form': 'patch-list-form', - 'bundle_name': newbundlename, + 'name': newbundlename, 'action': 'Create', 'project': self.project.id, } diff --git a/patchwork/views/__init__.py b/patchwork/views/__init__.py index 7700b734..5da8046d 100644 --- a/patchwork/views/__init__.py +++ b/patchwork/views/__init__.py @@ -3,11 +3,14 @@ # # SPDX-License-Identifier: GPL-2.0-or-later +import json + from django.contrib import messages from django.shortcuts import get_object_or_404 from django.db.models import Prefetch from patchwork.filters import Filters +from patchwork.forms import CreateBundleForm from patchwork.forms import MultiplePatchForm from patchwork.models import Bundle from patchwork.models import BundlePatch @@ -108,46 +111,34 @@ class Order(object): # TODO(stephenfin): Refactor this to break it into multiple, testable functions -def set_bundle(request, project, action, data, patches, context): +def set_bundle(request, project, action, data, patches): # set up the bundle bundle = None user = request.user if action == 'create': - bundle_name = data['bundle_name'].strip() - if '/' in bundle_name: - return ['Bundle names can\'t contain slashes'] - - if not bundle_name: - return ['No bundle name was specified'] - - if Bundle.objects.filter(owner=user, name=bundle_name).count() > 0: - return ['You already have a bundle called "%s"' % bundle_name] - + bundle_name = data['name'].strip() bundle = Bundle(owner=user, project=project, name=bundle_name) - bundle.save() - messages.success(request, "Bundle %s created" % bundle.name) + create_bundle_form = CreateBundleForm(instance=bundle, + data=request.POST) + if create_bundle_form.is_valid(): + create_bundle_form.save() + add_bundle_patches(request, patches, bundle) + bundle.save() + messages.success(request, 'Bundle %s created' % bundle.name) + else: + formErrors = json.loads(create_bundle_form.errors.as_json()) + errors = [e['message'] for e in formErrors['name']] + return errors elif action == 'add': + if not data['bundle_id']: + return ['No bundle was selected'] bundle = get_object_or_404(Bundle, id=data['bundle_id']) + add_bundle_patches(request, patches, bundle) elif action == 'remove': bundle = get_object_or_404(Bundle, id=data['removed_bundle_id']) - - if not bundle: - return ['no such bundle'] - - for patch in patches: - if action in ['create', 'add']: - bundlepatch_count = BundlePatch.objects.filter(bundle=bundle, - patch=patch).count() - if bundlepatch_count == 0: - bundle.append_patch(patch) - messages.success(request, "Patch '%s' added to bundle %s" % - (patch.name, bundle.name)) - else: - messages.warning(request, "Patch '%s' already in bundle %s" % - (patch.name, bundle.name)) - elif action == 'remove': + for patch in patches: try: bp = BundlePatch.objects.get(bundle=bundle, patch=patch) bp.delete() @@ -158,10 +149,21 @@ def set_bundle(request, project, action, data, patches, context): request, "Patch '%s' removed from bundle %s\n" % (patch.name, bundle.name)) + return [] - bundle.save() - return [] +def add_bundle_patches(request, patches, bundle): + for patch in patches: + bundlepatch_count = BundlePatch.objects.filter(bundle=bundle, + patch=patch).count() + if bundlepatch_count == 0: + bundle.append_patch(patch) + bundle.save() + messages.success(request, "Patch '%s' added to bundle %s" % + (patch.name, bundle.name)) + else: + messages.warning(request, "Patch '%s' already in bundle %s" % + (patch.name, bundle.name)) def generic_list(request, project, view, view_args=None, filter_settings=None, @@ -216,6 +218,7 @@ def generic_list(request, project, view, view_args=None, filter_settings=None, data = None user = request.user properties_form = None + create_bundle_form = None if user.is_authenticated: # we only pass the post data to the MultiplePatchForm if that was @@ -225,19 +228,20 @@ def generic_list(request, project, view, view_args=None, filter_settings=None, data_tmp = data properties_form = MultiplePatchForm(project, data=data_tmp) + create_bundle_form = CreateBundleForm() if request.method == 'POST' and data.get('form') == 'patch-list-form': action = data.get('action', '').lower() # special case: the user may have hit enter in the 'create bundle' # text field, so if non-empty, assume the create action: - if data.get('bundle_name', False): + if data.get('name', False): action = 'create' ps = Patch.objects.filter(id__in=get_patch_ids(data)) if action in bundle_actions: - errors = set_bundle(request, project, action, data, ps, context) + errors = set_bundle(request, project, action, data, ps) elif properties_form and action == properties_form.action: errors = process_multiplepatch_form(request, properties_form, @@ -288,6 +292,7 @@ def generic_list(request, project, view, view_args=None, filter_settings=None, context.update({ 'page': paginator.current_page, 'patchform': properties_form, + 'createbundleform': create_bundle_form, 'project': project, 'order': order, }) diff --git a/patchwork/views/patch.py b/patchwork/views/patch.py index 00b0147f..39ff9132 100644 --- a/patchwork/views/patch.py +++ b/patchwork/views/patch.py @@ -14,11 +14,11 @@ from django.urls import reverse from patchwork.forms import CreateBundleForm from patchwork.forms import PatchForm -from patchwork.models import Bundle from patchwork.models import Cover from patchwork.models import Patch from patchwork.models import Project from patchwork.views import generic_list +from patchwork.views import set_bundle from patchwork.views.utils import patch_to_mbox from patchwork.views.utils import series_patch_to_mbox @@ -60,6 +60,7 @@ def patch_detail(request, project_id, msgid): form = None createbundleform = None + errors = None if editable: form = PatchForm(instance=patch) @@ -71,34 +72,14 @@ def patch_detail(request, project_id, msgid): if action: action = action.lower() - if action == 'createbundle': - bundle = Bundle(owner=request.user, project=project) - createbundleform = CreateBundleForm(instance=bundle, - data=request.POST) - if createbundleform.is_valid(): - createbundleform.save() - bundle.append_patch(patch) - bundle.save() - createbundleform = CreateBundleForm() - messages.success(request, 'Bundle %s created' % bundle.name) - elif action == 'addtobundle': - bundle = get_object_or_404( - Bundle, id=request.POST.get('bundle_id')) - if bundle.append_patch(patch): - messages.success(request, - 'Patch "%s" added to bundle "%s"' % ( - patch.name, bundle.name)) - else: - messages.error(request, - 'Failed to add patch "%s" to bundle "%s": ' - 'patch is already in bundle' % ( - patch.name, bundle.name)) - - # all other actions require edit privs + if action in ['create', 'add']: + errors = set_bundle(request, project, action, + request.POST, [patch]) + elif not editable: return HttpResponseForbidden() - elif action is None: + elif action == 'update': form = PatchForm(data=request.POST, instance=patch) if form.is_valid(): form.save() @@ -135,6 +116,8 @@ def patch_detail(request, project_id, msgid): context['project'] = patch.project context['related_same_project'] = related_same_project context['related_different_project'] = related_different_project + if errors: + context['errors'] = errors return render(request, 'patchwork/submission.html', context) From patchwork Mon Aug 23 18:28:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raxel Gutierrez X-Patchwork-Id: 1519912 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=rDCPhrHd; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GtgkR1pLJz9sWS for ; Tue, 24 Aug 2021 04:29:19 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4GtgkR0jGbz2xsy for ; Tue, 24 Aug 2021 04:29:19 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=rDCPhrHd; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=flex--raxel.bounces.google.com (client-ip=2607:f8b0:4864:20::749; helo=mail-qk1-x749.google.com; envelope-from=33ugjyqukcu88rev2x55x2v.t536ratyd5812z9a9.5g2rs9.58x@flex--raxel.bounces.google.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=rDCPhrHd; dkim-atps=neutral Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Gtgjs27cVz2xfx for ; Tue, 24 Aug 2021 04:28:49 +1000 (AEST) Received: by mail-qk1-x749.google.com with SMTP id c27-20020a05620a165b00b003d3817c7c23so12408366qko.16 for ; Mon, 23 Aug 2021 11:28:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Yj5Nxv1voTGR8k3kjfxTjalSqla0cqV60CatsSkhiwA=; b=rDCPhrHdlW4f3pt6U8Ti7pm6SgbVk4CNG3f+Jd3iY7/gNw6uhEYIFkou6lMNjxBCHU t5MpzVdJEitG5tXR0JXRZQ52uvO0Y8JVRhMPPDDZcc/bHMweTsAhZ2EVa0Uhqm8a64Ag lYqqbn5D5CFW86D3Yf2BrTHyos5oRkAdjjvKYSyZxJvSRvS19FPhzS9PohoHfHFncM1A RzcHxCG1S7VWC6cd02EqNNLGyRTkWeXyd7uUpdhyWZvVM7Ix6qKMKxNH8usgoJu0xccF TDP0ydLimjHMxiFUmE4i0llb/P+1ib6QKo3VoitVaShEg5RF6EP//mi01U3KMopsINP2 j3nA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Yj5Nxv1voTGR8k3kjfxTjalSqla0cqV60CatsSkhiwA=; b=rK94j3+TvnrjSiL8B5QRgz1+vUjLZ13tNfaOdhGsoPeotajtUR7ncTnMWwC1jyMVp+ FA0gRY5hgiC2MnFoC0w9GtOtWjSYn5FXCRXFZSTo2iL26sCUZrZowdQ4wAV5Fs+1N/5D yL6JrJT/HpybfW4koTa5pKwYjmbny8gnMyPmqq7AwC02qiHxvzIzx2s8MvRqAkXhD+sp DGyfYQUhXEkK6E9T10MU0QXq5Pazj3pqu6wb+YsyJUBCCm8VIlUhqUm5bRQGpVbhfRkh SgR8AC8TQjzJGkNX7whx2aA8NyTdiVAEWCGE7xZyzlKYM+3DSNfk3qFP0BXBr/FFiieQ GADg== X-Gm-Message-State: AOAM530QzNsGFkxUvoBjd10KYRHPTEDMW6/NUERQFd7gUSd8jSUHjpIA cKyyARAQUK8aY2us+bWc0lS+s0bhYQUnsRi8UJeJJEZCideKKDGa8MIlRqQ3NLKYaZWE5DPjVQA +U67vz2Ug7ANtyUFI/4TI1xKLWtBcmReHlQdKh/c9JWE1bpIpR7DyZlF2REiL40La X-Google-Smtp-Source: ABdhPJzc5gkORBa4+9NrJ2HbqBLYoIv6+i/eLzsmQZ7KxlI2DXXi1BQQL5G4EWj3vKg/ZXXF3yERQZOpTg== X-Received: from raxel-pw.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2fda]) (user=raxel job=sendgmr) by 2002:a05:6214:965:: with SMTP id do5mr35028400qvb.0.1629743326556; Mon, 23 Aug 2021 11:28:46 -0700 (PDT) Date: Mon, 23 Aug 2021 18:28:32 +0000 In-Reply-To: <20210823182833.3976100-1-raxel@google.com> Message-Id: <20210823182833.3976100-5-raxel@google.com> Mime-Version: 1.0 References: <20210823182833.3976100-1-raxel@google.com> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog Subject: [PATCH v4 4/5] patch-list: style modification forms as an action bar From: Raxel Gutierrez To: patchwork@lists.ozlabs.org X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Add styling to the new patch list html code to make the change property and bundle action forms more usable. Before [1] and after [2] images for reference. [1] https://i.imgur.com/Pzelipp.png [2] https://i.imgur.com/UtNJXuf.png Signed-off-by: Raxel Gutierrez --- htdocs/css/style.css | 73 ++++++++++++++++++++++++++++++++++++-------- patchwork/forms.py | 44 ++++++++++++++++++++------ 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/htdocs/css/style.css b/htdocs/css/style.css index 4ad503da..3ed1745b 100644 --- a/htdocs/css/style.css +++ b/htdocs/css/style.css @@ -146,10 +146,6 @@ a.col-inactive:hover { div.filters { } -div.patch-forms { - margin-top: 1em; -} - /* list order manipulation */ table.patch-list tr.draghover { @@ -173,7 +169,7 @@ input#reorder-change { .paginator { text-align: right; clear: both; - margin: 8px 0 15px; + margin: 8px 0 15px; } .paginator .prev-na, @@ -405,13 +401,62 @@ table.bundlelist td padding-right: 2em; } +.patch-list-actions { + width: 100%; + display: inline-flex; + flex-wrap: wrap; + justify-content: space-between; +} + /* forms that appear for a patch */ +.patch-forms { + display: inline-flex; + flex-wrap: wrap; + margin: 16px 0px; +} + div.patch-form { - border: thin solid #080808; - padding-left: 0.6em; - padding-right: 0.6em; - float: left; - margin: 0.5em 5em 0.5em 10px; + display: flex; + flex-wrap: wrap; + align-items: center; +} + +select[class^=change-property-], .archive-patch-select, .add-bundle { + padding: 4px; + margin-right: 8px; + box-sizing: border-box; + border-radius: 4px; + background-color: var(--light-color); +} + +#patch-form-archive { + display: flex; + align-items: center; + margin-right: 4px; +} + +#patch-form-archive > label { + margin: 0px; +} + +#patch-form-archive > select, #patch-form-archive > input { + margin: 0px 4px 0px 4px; +} + +.patch-form-submit { + font-weight: bold; + padding: 4px; +} + +#patch-form-bundle, #add-to-bundle, #remove-bundle { + margin-left: 16px; +} + +.create-bundle { + padding: 4px; + margin-right: 8px; + box-sizing: border-box; + border-radius: 4px; } div.patch-form h3 { @@ -430,15 +475,17 @@ div.patch-form ul { margin-top: 0em; } -/* forms */ -table.form { +.create-bundle { + padding: 4px; + margin-right: 8px; + box-sizing: border-box; + border-radius: 4px; } span.help_text { font-size: 80%; } - table.form td { padding: 0.6em; vertical-align: top; diff --git a/patchwork/forms.py b/patchwork/forms.py index 33103f4d..0825784b 100644 --- a/patchwork/forms.py +++ b/patchwork/forms.py @@ -53,7 +53,10 @@ class EmailForm(forms.Form): class BundleForm(forms.ModelForm): name = forms.RegexField( regex=r'^[^/]+$', min_length=1, max_length=50, required=False, - error_messages={'invalid': 'Bundle names can\'t contain slashes'}) + error_messages={'invalid': 'Bundle names can\'t contain slashes'}, + widget=forms.TextInput( + attrs={'class': 'create-bundle', + 'placeholder': 'Bundle name'})) class Meta: model = Bundle @@ -120,18 +123,28 @@ class PatchForm(forms.ModelForm): def __init__(self, instance=None, project=None, *args, **kwargs): super(PatchForm, self).__init__(instance=instance, *args, **kwargs) self.fields['delegate'] = forms.ModelChoiceField( - queryset=_get_delegate_qs(project, instance), required=False) + queryset=_get_delegate_qs(project, instance), + widget=forms.Select(attrs={'class': 'change-property-delegate'}), + required=False) class Meta: model = Patch fields = ['state', 'archived', 'delegate'] + widgets = { + 'state': forms.Select( + attrs={'class': 'change-property-state'}), + 'archived': forms.CheckboxInput( + attrs={'class': 'archive-patch-check'}), + } class OptionalModelChoiceField(forms.ModelChoiceField): - no_change_choice = ('*', 'no change') + no_change_choice = ('*', 'No change') to_field_name = None - def __init__(self, *args, **kwargs): + def __init__(self, *args, placeholder, className, **kwargs): + self.no_change_choice = ('*', placeholder) + self.widget = forms.Select(attrs={'class': className}) super(OptionalModelChoiceField, self).__init__( initial=self.no_change_choice[0], *args, **kwargs) @@ -160,6 +173,10 @@ class OptionalModelChoiceField(forms.ModelChoiceField): class OptionalBooleanField(forms.TypedChoiceField): + def __init__(self, className, *args, **kwargs): + self.widget = forms.Select(attrs={'class': className}) + super(OptionalBooleanField, self).__init__(*args, **kwargs) + def is_no_change(self, value): return value == self.empty_value @@ -167,17 +184,26 @@ class OptionalBooleanField(forms.TypedChoiceField): class MultiplePatchForm(forms.Form): action = 'update' archived = OptionalBooleanField( - choices=[('*', 'no change'), ('True', 'Archived'), - ('False', 'Unarchived')], + className="archive-patch-select", + choices=[('*', 'No change'), ('True', 'Archive'), + ('False', 'Unarchive')], coerce=lambda x: x == 'True', - empty_value='*') + empty_value='*', + label="Archived") def __init__(self, project, *args, **kwargs): super(MultiplePatchForm, self).__init__(*args, **kwargs) self.fields['delegate'] = OptionalModelChoiceField( - queryset=_get_delegate_qs(project=project), required=False) + queryset=_get_delegate_qs(project=project), + placeholder="Delegate to", + className="change-property-delegate", + label="Delegate to", + required=False) self.fields['state'] = OptionalModelChoiceField( - queryset=State.objects.all()) + queryset=State.objects.all(), + placeholder="Change state", + className="change-property-state", + label="Change state") def save(self, instance, commit=True): opts = instance.__class__._meta From patchwork Mon Aug 23 18:28:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raxel Gutierrez X-Patchwork-Id: 1519913 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=112.213.38.117; helo=lists.ozlabs.org; envelope-from=patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=Z7QL9wVS; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GtgkZ1VWRz9sWS for ; Tue, 24 Aug 2021 04:29:26 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4GtgkZ0JJnz2yJS for ; Tue, 24 Aug 2021 04:29:26 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=Z7QL9wVS; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=flex--raxel.bounces.google.com (client-ip=2607:f8b0:4864:20::74a; helo=mail-qk1-x74a.google.com; envelope-from=33-gjyqukcva9sfw3y66y3w.u647sbuze69230aba.6h3sta.69y@flex--raxel.bounces.google.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=Z7QL9wVS; dkim-atps=neutral Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Gtgjt4rHbz2xfx for ; Tue, 24 Aug 2021 04:28:50 +1000 (AEST) Received: by mail-qk1-x74a.google.com with SMTP id e22-20020a05620a209600b003d5ff97bff7so8814630qka.1 for ; Mon, 23 Aug 2021 11:28:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=3hvG3j6DNgGxDO5MuX2ew6doHO5uZVcfED4myevbfcI=; b=Z7QL9wVSZ0cKNtTxQ6pRtgi+56iYWTJFhf0ud2YpzZ5kVo+w1HtgIASSzy6p+t3TD/ NJCTYk0Rt6hpff9k+twCIwgANrUadVDl47s4WBzsesBMsrkzTQ/5gLza/ca4joJV8iYx /xXl6LbSJKqigDjeplyegvq1rZkZhDYGk11Cg4eOlcAO0IQmCE9oTGmyc7cVcA0fMBkW pcBsKe640sIa+zE1chw/AvL7lHxCGUm9ZhFe8jIHDbhGjdaYc3jNfVPeQxBmk8+ItDNx mSvsr8U0M7LzXmXBUax4ilhq8JL6FFMlg9W2x0gVVwN+svvgd+xtNXhvP/5vX5Dn76eR kzPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=3hvG3j6DNgGxDO5MuX2ew6doHO5uZVcfED4myevbfcI=; b=jIoUIJuiNDHdaIb0gFTiibIOA1t16wEVB+/prG+9EVvTPWVtAzYflRrLuNKVHAT3A6 KliYSfJKSbhU6PXo4CvrUUEyEvIEoF5VTkGxhP9BBeKSD4+QRu/Yv77ydavBozbwVhTG 9P2GmunNf8ElmrTdebkrzq8fKbp47SA9tmqsyfovRdaFh9OEYRNJ3G1vqrKhq5HaG4cT aqwpNvYuIjWuwvWnDxunrggSYJyfC6x2dlznn/9UxhTQC3RQesir3cwpMHV46L8jLrZf 2PEOMtj28a7I7WF0URE9Q5/PerJzjP0CcAUFcpiuMAgte7dzlk3ThK7jILn6Zo0cd6kB hMqQ== X-Gm-Message-State: AOAM532GdrQjDFVr+UGNLi/17K3Dlrr+QR9IF/f0WNPGlkcIdIrR7I60 e5TBALf7I0/rvhMG0mBPM19VmA2v/pjX1jXJDNMGZysQWAtUuCGY9GJvnQGoFjiwYqKl4AFdbUS wN3rH6pFS/1OXtLk4t8RQqOxz57aFto3HQF/PVaoaZgkm+7yNTnOI/NddTGOJGijF X-Google-Smtp-Source: ABdhPJz65rDalVUh/rrhccWDrPW4Naj1XJHFXl0UkA63iKvS2irWEcTXQ9Vk0P18nCtOl7dALZjz5sYQbg== X-Received: from raxel-pw.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2fda]) (user=raxel job=sendgmr) by 2002:ad4:5bc8:: with SMTP id t8mr34274582qvt.18.1629743327987; Mon, 23 Aug 2021 11:28:47 -0700 (PDT) Date: Mon, 23 Aug 2021 18:28:33 +0000 In-Reply-To: <20210823182833.3976100-1-raxel@google.com> Message-Id: <20210823182833.3976100-6-raxel@google.com> Mime-Version: 1.0 References: <20210823182833.3976100-1-raxel@google.com> X-Mailer: git-send-email 2.33.0.rc2.250.ged5fa647cd-goog Subject: [PATCH v4 5/5] patch-list: add inline dropdown for delegate and state one-off changes From: Raxel Gutierrez To: patchwork@lists.ozlabs.org X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Add dropdown for the cell values of the Delegate and State columns for each individual patch to make one-off changes to patches. The dropdowns are only viewable if the user has patch edit permissions. Change the generic_list method to pass the list of states and maintainers to the patch list view context to populate the dropdown options. The static patch-list.js file now uses the modularity of the fetch request and update/error messages handling of rest.js. TODO: The loading of the patch-list page is very slow now because it seems that for each call to check if a patch is editable by a user, the db is accessed. Changes in the backend need to be made so this is done with only done with only one call to the db. Signed-off-by: Raxel Gutierrez --- htdocs/README.rst | 6 +++ htdocs/js/patch-list.js | 52 ++++++++++++++++++- .../patchwork/partials/patch-list.html | 35 +++++++++++-- patchwork/views/__init__.py | 6 +++ 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/htdocs/README.rst b/htdocs/README.rst index 6c435124..32550119 100644 --- a/htdocs/README.rst +++ b/htdocs/README.rst @@ -133,6 +133,12 @@ js Part of Patchwork. +``patch-list.js.`` + Event helpers and other application logic for patch-list.html. These + support patch list manipulation (e.g. inline dropdown changes). + + Part of Patchwork. + ``selectize.min.js`` Selectize is the hybrid of a ``textbox`` and ``
{{ patch|patch_checks }} {{ patch.date|date:"Y-m-d" }} {{ patch.submitter|personify:project }}{{ patch.delegate.username }}{{ patch.state }} + {% if patch.is_editable %} + + {% else %} + {{ patch.delegate.username }} + {% endif %} + + {% if patch.is_editable %} + + {% else %} + {{ patch.state }} + {% endif %} +