diff --git a/kitsune/flagit/jinja2/flagit/content_moderation.html b/kitsune/flagit/jinja2/flagit/content_moderation.html
index 861ddddcb56..dae149f4f95 100644
--- a/kitsune/flagit/jinja2/flagit/content_moderation.html
+++ b/kitsune/flagit/jinja2/flagit/content_moderation.html
@@ -1,4 +1,5 @@
{% extends "flagit/flagit_base.html" %}
+{% from "flagit/includes/macros.html" import filter_dropdown %}
{% block flagged_items %}
{% for object in objects %}
@@ -39,6 +40,17 @@
-
{{ _('Content Pending Moderation') }}
-
+
{{ _('Content Pending Moderation') }}
+
{% block flagged_items %}
{% endblock %}
@@ -26,7 +26,7 @@ {{ _('Content Pending Moderation') }}
{{ for_contributors_sidebar(user, settings.WIKI_DEFAULT_LANGUAGE, active="flagit.flagged_queue", menu="contributor-tools", locale=locale) }}
- {% block side_top_reason %}
+ {% block filter_dropdown %}
{% endblock %}
{% endblock %}
diff --git a/kitsune/flagit/jinja2/flagit/includes/macros.html b/kitsune/flagit/jinja2/flagit/includes/macros.html
index ef8185e7119..2981f6a9284 100644
--- a/kitsune/flagit/jinja2/flagit/includes/macros.html
+++ b/kitsune/flagit/jinja2/flagit/includes/macros.html
@@ -3,3 +3,19 @@
{{date}} by
{{user}}
{% endtrans %}
{%- endmacro %}
+
+{% macro filter_dropdown(form_id, select_id, label, name, default_option, options, selected_filter) %}
+
+
+
+{% endmacro %}
diff --git a/kitsune/flagit/jinja2/flagit/queue.html b/kitsune/flagit/jinja2/flagit/queue.html
index 8eae3ad548f..6555593d484 100644
--- a/kitsune/flagit/jinja2/flagit/queue.html
+++ b/kitsune/flagit/jinja2/flagit/queue.html
@@ -1,4 +1,5 @@
{% extends "flagit/flagit_base.html" %}
+{% from "flagit/includes/macros.html" import filter_dropdown %}
{% block flagged_items %}
{% for object in objects %}
@@ -49,17 +50,6 @@
{{ _('Update Status:') }}
{% endfor %}
{% endblock %}
-{% block side_top_reason %}
-
-
-
-
+{% block filter_dropdown %}
+ {{ filter_dropdown("reason-filter-form", "flagit-reason-filter", "Filter by reason:", "reason", "All reasons", reasons, selected_reason) }}
{% endblock %}
diff --git a/kitsune/flagit/views.py b/kitsune/flagit/views.py
index 2e154e6ee2b..58f04b04a39 100644
--- a/kitsune/flagit/views.py
+++ b/kitsune/flagit/views.py
@@ -9,7 +9,7 @@
from kitsune.access.decorators import login_required, permission_required
from kitsune.flagit.models import FlaggedObject
-from kitsune.products.models import Topic
+from kitsune.products.models import Product, Topic
from kitsune.questions.events import QuestionReplyEvent
from kitsune.questions.models import Answer, Question
from kitsune.sumo.templatetags.jinja_helpers import urlparams
@@ -17,7 +17,7 @@
from kitsune.tags.models import SumoTag
-def get_flagged_objects(reason=None, exclude_reason=None, content_model=None):
+def get_flagged_objects(reason=None, exclude_reason=None, content_model=None, product_slug=None):
"""Retrieve pending flagged objects with optional filtering, eager loading related fields."""
queryset = FlaggedObject.objects.pending().select_related("content_type", "creator")
if exclude_reason:
@@ -26,6 +26,14 @@ def get_flagged_objects(reason=None, exclude_reason=None, content_model=None):
queryset = queryset.filter(reason=reason)
if content_model:
queryset = queryset.filter(content_type=content_model)
+ if product_slug:
+ matching_product_ids = [
+ obj.id
+ for obj in queryset
+ if hasattr(obj.content_object, "product")
+ and obj.content_object.product.slug == product_slug
+ ]
+ queryset = queryset.filter(id__in=matching_product_ids)
return queryset
@@ -119,11 +127,14 @@ def get_hierarchical_topics(topics, parent=None, level=0):
@permission_required("flagit.can_moderate")
def moderate_content(request):
"""Display flagged content that needs moderation."""
- content_type = ContentType.objects.get_for_model(Question)
+ product_slug = request.GET.get("product")
+ content_type = ContentType.objects.get_for_model(Question)
objects = (
get_flagged_objects(
- reason=FlaggedObject.REASON_CONTENT_MODERATION, content_model=content_type
+ reason=FlaggedObject.REASON_CONTENT_MODERATION,
+ content_model=content_type,
+ product_slug=product_slug,
)
.select_related("content_type", "creator")
.prefetch_related("content_object__product")
@@ -143,6 +154,8 @@ def moderate_content(request):
{
"objects": objects,
"locale": request.LANGUAGE_CODE,
+ "products": [(p.slug, p.title) for p in Product.active.filter(codename="")],
+ "selected_product": product_slug,
},
)
diff --git a/kitsune/sumo/static/sumo/js/flagit.js b/kitsune/sumo/static/sumo/js/flagit.js
index e5e427c8716..04bd78f9b3c 100644
--- a/kitsune/sumo/static/sumo/js/flagit.js
+++ b/kitsune/sumo/static/sumo/js/flagit.js
@@ -127,37 +127,40 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
- async function updateReasonAndFetchContent(reason) {
- const url = new URL(window.location.href);
- if (reason) {
- url.searchParams.set('reason', reason);
- window.history.pushState({}, '', url);
- } else {
- url.searchParams.delete('reason');
- window.history.replaceState({}, '', url.pathname);
- }
+ const flaggedQueue = document.getElementById('flagged-queue');
+ initializeFilterDropdown('flagit-reason-filter', 'reason');
+ initializeFilterDropdown('flagit-product-filter', 'product');
- const response = await fetchData(url);
- if (response) {
- const parser = new DOMParser();
- const doc = parser.parseFromString(await response.text(), 'text/html');
- flaggedQueue.innerHTML = doc.querySelector('#flagged-queue').innerHTML;
- disableUpdateStatusButtons();
- initializeDropdownsAndTags();
+ function initializeFilterDropdown(filterId, queryParam) {
+ const filterElement = document.getElementById(filterId);
+ if (!filterElement) return;
+
+ const currentFilter = new URL(window.location.href).searchParams.get(queryParam);
+ if (currentFilter) {
+ filterElement.value = currentFilter;
}
- }
- const reasonFilter = document.getElementById('flagit-reason-filter');
- const flaggedQueue = document.getElementById('flagged-queue');
+ filterElement.addEventListener('change', async () => {
+ const selectedValue = filterElement.value;
+ const url = new URL(window.location.href);
- if (reasonFilter) {
- const reason = new URL(window.location.href).searchParams.get('reason');
- if (reason) reasonFilter.value = reason;
+ if (selectedValue) {
+ url.searchParams.set(queryParam, selectedValue);
+ } else {
+ url.searchParams.delete(queryParam);
+ }
+ window.history.pushState({}, '', url);
- reasonFilter.addEventListener('change', async () => {
- const selectedReason = reasonFilter.value;
- await updateReasonAndFetchContent(selectedReason);
+ const response = await fetchData(url);
+ if (response) {
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(await response.text(), 'text/html');
+ flaggedQueue.innerHTML = doc.querySelector('#flagged-queue').innerHTML;
+ disableUpdateStatusButtons();
+ initializeDropdownsAndTags();
+ }
});
}
+
initializeDropdownsAndTags();
});