From patchwork Wed Jul 28 15:24:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raxel Gutierrez X-Patchwork-Id: 1510903 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=vN0nzRhi; 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 4GZcst2Ry6z9s5R for ; Thu, 29 Jul 2021 01:25:06 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4GZcst1ZPTz30HY for ; Thu, 29 Jul 2021 01:25: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=vN0nzRhi; 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=3sxybyqukcbijspwdyggydw.ugehsluzogjcdaklk.grdstk.gjy@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=vN0nzRhi; 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 4GZcsJ2X3mz30D9 for ; Thu, 29 Jul 2021 01:24:36 +1000 (AEST) Received: by mail-qk1-x74a.google.com with SMTP id e11-20020a05620a208bb02903b854c43335so1266387qka.21 for ; Wed, 28 Jul 2021 08:24:35 -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=qG8jDPbIFG35OvHAb+2D8my4VfJ1mf3y4byVg06OYlQ=; b=vN0nzRhittx0T4i9DY9KsrzP433yLHvd/bEZBRTyD+P7YhNzSwQXQ6S5xHk/R/POWv pArRGmPSdQ5yzTtqUBaFr0672Aok1oW3KvYFoRteu0ox6kY47H/PjHHXFxMPGh/tpPzz CdGBEiZZcPqo5mjAmctmTa712tdm49u8zTVQu4OjLs6dHQ6u/zOfpN0sgriwcmtS1Zae X6MKoJddzqDtDzGdZuHoiiPTzL6Uw8YiyXSeU/h8DI+MEnKiR0zj2ur92TCv0AUktKAw O+CUvtrGZH8v7m2upN3afb7B/GKfxNCVWlYmaTYxNNTY2wQiD9uoegcPznMUVhCJ0qiz R3Aw== 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=qG8jDPbIFG35OvHAb+2D8my4VfJ1mf3y4byVg06OYlQ=; b=HOPAaw+Ne+qUtT7FxtmzlpTHcmSWaWIouyO2QeLeetTOB1Nm1BUF0z8klxqQcBaSzv 78DbE50NjPKyLZC6VWCHzm1N3tVu89jAeuL1Bc88xVdy4AT8vkJeEhlQxUTnFCJR7cRo 8AV7rfrWL/KlYwpkT65NPOi+CANaYHNJxvC72ixw6d37hnXLjWEKrvi2BumOhuFDv3M8 anPTyX53xmkK2mfd/fCAIjT11UVst/Syblm9R16NLFdZZtNsZEPmPzGQ9fIWO3M386q0 Z/db5NpfJtUyVUdNrd+ateC+VedDKGv467MkpBiyIFYrFdovKQ4JRmgyKMA3CrPhYLOC g7Og== X-Gm-Message-State: AOAM532sQ6/91RrL7lORLB1ByvKVWeZT/HBr6Q1w+XAc3Rh26psxdLAd 7GTyprsLskcV1hNmqyQnDjkL08zZ7F7v6wX2lQSLuDD0MSBpOEuA82KPvfaktTEYblwzng9doHN 5CIHYVu/prbLYzvfg4uPd8rMd787M/06Gr0eHBlaHvuso3ZGPH28oEFNDHVzqTL4Z X-Google-Smtp-Source: ABdhPJyqpE7nV26yrwbfVfiLLHTPDl370NFtAiQJjiFlPFhTYO/E4p3U0o1fTVjaDTUqF4LIwdeq/OMzEw== X-Received: from raxel-pw.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2fda]) (user=raxel job=sendgmr) by 2002:a05:6214:1585:: with SMTP id m5mr136344qvw.48.1627485873033; Wed, 28 Jul 2021 08:24:33 -0700 (PDT) Date: Wed, 28 Jul 2021 15:24:19 +0000 In-Reply-To: <20210728152419.3588812-1-raxel@google.com> Message-Id: <20210728152419.3588812-6-raxel@google.com> Mime-Version: 1.0 References: <20210728152419.3588812-1-raxel@google.com> X-Mailer: git-send-email 2.32.0.554.ge1b32706d8-goog Subject: [PATCH v3 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 when logged in and revert selections made by users that don't have permission to change a given patch's state or delegate. 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. Signed-off-by: Raxel Gutierrez --- htdocs/js/patch-list.js | 48 +++++++++++++++++++ htdocs/js/rest.js | 2 +- .../patchwork/partials/patch-list.html | 40 ++++++++++++++-- patchwork/views/__init__.py | 3 ++ templates/base.html | 2 +- 5 files changed, 90 insertions(+), 5 deletions(-) diff --git a/htdocs/js/patch-list.js b/htdocs/js/patch-list.js index 5c94e66..13f890d 100644 --- a/htdocs/js/patch-list.js +++ b/htdocs/js/patch-list.js @@ -1,4 +1,31 @@ +import { updateProperty } from "./rest.js"; + $( document ).ready(function() { + let inlinePropertyDropdowns = $("td > select[class^='change-property-']"); + $(inlinePropertyDropdowns).each(function() { + // Store previous dropdown selection + $(this).data("prevProperty", $(this).val()); + }); + + // Change listener for dropdowns that change an individual patch's delegate and state properties + $(inlinePropertyDropdowns).change((event) => { + const property = event.target.getAttribute("value"); + const { url, data } = getPatchProperties(event.target, property); + const updateMessage = { + 'none': "No patches updated", + 'some': "1 patch updated", + }; + updateProperty(url, data, updateMessage).then(is_success => { + if (!is_success) { + // Revert to previous selection + $(event.target).val($(event.target).data("prevProperty")); + } else { + // Update to new previous selection + $(event.target).data("prevProperty", $(event.target).val()); + } + }); + }); + $("#patchlist").stickyTableHeaders(); $("#check-all").change(function(e) { @@ -9,4 +36,25 @@ $( document ).ready(function() { } e.preventDefault(); }); + + /** + * Returns the data to make property changes to a patch through fetch request. + * @param {Element} propertySelect Property select element modified. + * @param {string} property Patch property modified (e.g. "state", "delegate") + * @return {{property: string, value: string}} + * property: Property field to be modified in request. + * value: New value for property to be modified to in request. + */ + function getPatchProperties(propertySelect, property) { + const selectedOption = propertySelect.options[propertySelect.selectedIndex]; + const patchId = propertySelect.parentElement.parentElement.dataset.patchId; + const propertyValue = (property === "state") ? selectedOption.text + : (selectedOption.value === "*") ? null : selectedOption.value + const data = {}; + data[property] = propertyValue; + return { + "url": "/api/patches/" + patchId + "/", + "data": data, + }; + } }); diff --git a/htdocs/js/rest.js b/htdocs/js/rest.js index 18c0295..ede7295 100644 --- a/htdocs/js/rest.js +++ b/htdocs/js/rest.js @@ -69,4 +69,4 @@ function handleErrorMessages(errorMessage) { container.prepend(errorHeader); } -export { updateProperty, handleUpdateMessages, handleUpdateMessages}; \ No newline at end of file +export { updateProperty }; \ 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 5e2f0dd..90b22d1 100644 --- a/patchwork/templates/patchwork/partials/patch-list.html +++ b/patchwork/templates/patchwork/partials/patch-list.html @@ -5,7 +5,7 @@ {% load static %} {% block headers %} - + {% endblock %} {% include "patchwork/partials/filters.html" %} @@ -187,8 +187,42 @@ {{ patch|patch_checks }} {{ patch.date|date:"Y-m-d" }} {{ patch.submitter|personify:project }} - {{ patch.delegate.username }} - {{ patch.state }} + + + {% if user.is_authenticated %} + + {% else %} + {{ patch.delegate.username }} + {% endif %} + + + {% if user.is_authenticated %} + + {% else %} + {{ patch.state }} + {% endif %} + {% empty %} diff --git a/patchwork/views/__init__.py b/patchwork/views/__init__.py index 3ea2af4..c70c6be 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 @@ -178,6 +179,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 diff --git a/templates/base.html b/templates/base.html index 8700602..e57e2d5 100644 --- a/templates/base.html +++ b/templates/base.html @@ -114,7 +114,7 @@ {% endfor %} {% endif %} -
+
{% block body %} {% endblock %}