Skip to content

Commit 4b42119

Browse files
authored
Fix the rounds dropdown menu search on the all view. (#4784)
* Add unpublished and not started filter to round admin list in wagtail. * Add unpublished filter to rounds view. * Fix headers in filter dropdown on rounds view. * Fix unstyled pagination on rounds view. Instead of tabs make open/closed look like this to make the filter in the dropdown work: <img width="361" height="483" alt="Skärmavbild 2026-03-27 kl 17 53 51" src="https://github.com/user-attachments/assets/3a18f3e8-6172-422b-9c46-25eed18151c9" />
1 parent ee764e8 commit 4b42119

5 files changed

Lines changed: 80 additions & 84 deletions

File tree

hypha/apply/funds/admin_helpers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def lookups(self, request, model_admin):
8989
return (
9090
("open", _("Open")),
9191
("closed", _("Closed")),
92+
("new", _("Not started")),
93+
("unpublished", _("Unpublished")),
9294
)
9395

9496
def queryset(self, request, queryset):
@@ -97,6 +99,10 @@ def queryset(self, request, queryset):
9799
return queryset.open()
98100
elif value == "closed":
99101
return queryset.closed()
102+
elif value == "new":
103+
return queryset.new()
104+
elif value == "unpublished":
105+
return queryset.not_live()
100106
return queryset
101107

102108

hypha/apply/funds/models/applications.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ def serve(self, request):
220220

221221

222222
class RoundBaseManager(PageQuerySet):
223+
def new(self):
224+
rounds = self.live().public().specific()
225+
rounds = rounds.filter(start_date__gt=date.today())
226+
return rounds
227+
223228
def open(self):
224229
rounds = self.live().public().specific()
225230
rounds = rounds.filter(

hypha/apply/funds/tables.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ def __init__(self, *args, **kwargs):
400400
class Meta:
401401
fields = ("title", "fund", "lead", "start_date", "end_date", "deterrmined")
402402
attrs = {"class": "table"}
403+
template_name = "funds/tables/table.html"
403404

404405
def render_lead(self, value):
405406
return format_html("<span>{}</span>", value)
@@ -455,7 +456,12 @@ def __init__(self, *args, **kwargs):
455456
super().__init__(
456457
self,
457458
*args,
458-
choices=[("open", "Open"), ("closed", "Closed"), ("new", "Not Started")],
459+
choices=[
460+
("open", _("Open")),
461+
("closed", _("Closed")),
462+
("new", _("Not Started")),
463+
("unpublished", _("Unpublished")),
464+
],
459465
**kwargs,
460466
)
461467

@@ -468,6 +474,8 @@ def filter(self, qs, value):
468474
return qs.closed()
469475
if value == "new":
470476
return qs.new()
477+
if value == "unpublished":
478+
return qs.not_live()
471479

472480
return qs.open()
473481

@@ -476,7 +484,7 @@ class RoundsFilter(filters.FilterSet):
476484
fund = ModelMultipleChoiceFilter(queryset=get_used_funds, label=_("Funds"))
477485
lead = ModelMultipleChoiceFilter(queryset=get_round_leads, label=_("Leads"))
478486
active = ActiveRoundFilter(label=_("Active"))
479-
round_state = OpenRoundFilter(label=_("Open"))
487+
round_state = OpenRoundFilter(label=_("State"))
480488

481489

482490
class ReviewerLeaderboardFilterForm(forms.ModelForm):

hypha/apply/funds/templates/funds/includes/table_filter_and_search.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ <h2 class="section-header">{{ heading }}</h2>
7777
{% if filter.form %}
7878
<nav class="flex flex-wrap gap-2 items-center menu-filters">
7979
{% if not field|is_datefilter %}
80-
<c-dropdown-menu title=field.label heading=field|get_dropdown_heading enable_search=True position="right">
80+
<c-dropdown-menu title=field.label heading="{{ field|get_dropdown_heading }}" enable_search=True position="right">
8181
<ul class="flex overflow-auto flex-col max-h-80 text-gray-700 divide-y" data-filter-list>
8282
{% for value, label in filter.form|get_field_choices:field_name %}
8383
{% get_item_value filter.form field_name as selected_value %}
@@ -103,7 +103,7 @@ <h2 class="section-header">{{ heading }}</h2>
103103
</ul>
104104
</c-dropdown-menu>
105105
{% else %}
106-
<c-dropdown-menu title=field.label heading=field|get_dropdown_heading position="right">
106+
<c-dropdown-menu title=field.label heading="{{ field|get_dropdown_heading }}" position="right">
107107
<calendar-range class="mx-auto cally" onchange="updateURL(this.value, '{{field_name}}')" data-field-name='{{field_name}}'>
108108
{% heroicon_micro "chevron-left" aria_label="Previous" slot="previous" aria_hidden=true size=18 %}
109109
{% heroicon_micro "chevron-right" aria_label="Next" slot="next" aria_hidden=true size=18 %}
Lines changed: 57 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,82 @@
11
{% load i18n %}
22
{% load querystrings heroicons %}
33

4-
<div class='flex flex-col'>
5-
4+
<div class="flex flex-col">
65
{% if open_rounds or closed_rounds %}
76

87
{% if selected_rounds %}
98
<a
109
href="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" "round" %}"
1110
hx-get="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" "round" %}"
1211
hx-push-url="true"
13-
class="flex px-3 py-2 text-base-content/80 border-b items-center hover:bg-base-200 focus:bg-base-200{% if s.selected %}bg-base-200{% endif %}">
12+
class="flex items-center py-2 px-3 border-b text-base-content/80 hover:bg-base-200 focus:bg-base-200">
1413
{% trans "All Rounds" %}
1514
</a>
1615
{% endif %}
1716

18-
<div
19-
role="tablist"
17+
<ul class="overflow-auto max-h-80 divide-y" data-filter-list>
18+
2019
{% if open_rounds %}
21-
x-data="{tab: 'open_rounds'}"
22-
{% else %}
23-
x-data="{tab: 'closed_rounds'}"
20+
{# Section heading — hidden during search because data-filter-item-text is empty #}
21+
<li class="py-1 px-3 text-xs font-semibold tracking-wide uppercase text-base-content/50 bg-base-200" aria-hidden="true">
22+
<span data-filter-item-text></span>
23+
{% trans "Open" %}
24+
</li>
25+
{% for f in open_rounds %}
26+
<li>
27+
<a
28+
data-filter-item-text
29+
{% if f.selected %}
30+
href="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
31+
hx-get="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
32+
{% else %}
33+
href="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
34+
hx-get="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
35+
{% endif %}
36+
hx-push-url="true"
37+
class="flex {% if f.selected %}ps-2 font-medium bg-base-200{% else %}ps-8{% endif %} pe-3 py-2 text-base-content/80 items-center hover:bg-base-200 focus:bg-base-200">
38+
{% if f.selected %}
39+
{% heroicon_mini "check" aria_hidden="true" size=16 class="stroke-2 me-1" %}
40+
{% endif %}
41+
{{ f.title }}
42+
</a>
43+
</li>
44+
{% endfor %}
2445
{% endif %}
25-
>
26-
<nav class="flex px-3 pt-2" style="box-shadow: inset 0 -1px 0 #e5e7eb">
27-
28-
{% if open_rounds %}
29-
<span @click="tab = 'open_rounds'"
30-
role="tab"
31-
:class="{ 'border-x border-t border-b-transparent': tab === 'open_rounds' }"
32-
class="inline-block py-2 px-4 text-center rounded-t-lg border-b cursor-pointer bg-base-100 round hover:text-base-content">{% trans "Open" %}</span>
33-
{% endif %}
34-
35-
{% if closed_rounds %}
36-
<span @click="tab = 'closed_rounds'"
37-
role="tab"
38-
:class="{ 'border-x border-t border-b-transparent': tab === 'closed_rounds' }"
39-
class="inline-block py-2 px-4 text-center rounded-t-lg border-b cursor-pointer bg-base-100 hover:text-base-content">{% trans "Closed" %}</span>
40-
{% endif %}
41-
</nav>
4246

43-
<div data-filter-list>
44-
{% if closed_rounds %}
45-
<div class="overflow-auto max-h-80 divide-y tab-closed-rounds"
46-
x-show="tab === 'closed_rounds'"
47-
:aria-hidden="tab === 'closed_rounds' ? 'false' : 'true'"
48-
role="tabpanel"
49-
>
50-
{% for f in closed_rounds %}
51-
<a data-filter-item-text
52-
{% if f.selected %}
53-
href="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
54-
hx-get="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
55-
{% else %}
56-
href="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
57-
hx-get="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
58-
{% endif %}
59-
60-
hx-push-url="true"
61-
class="flex {% if f.selected %}ps-2 font-medium{% else %}ps-8{% endif %} pe-3 py-2 text-base-content/80 items-center hover:bg-base-200 focus:bg-base-200{% if f.selected %}bg-base-200{% endif %}">
62-
{% if f.selected %}
63-
{% heroicon_mini "check" aria_hidden="true" size=16 class="stroke-2 me-1" %}
64-
{% endif %}
65-
{{ f.title }}
66-
</a>
67-
{% endfor %}
68-
</div>
69-
{% endif %}
47+
{% if closed_rounds %}
48+
{# Section heading — hidden during search because data-filter-item-text is empty #}
49+
<li class="py-1 px-3 text-xs font-semibold tracking-wide uppercase text-base-content/50 bg-base-200" aria-hidden="true">
50+
<span data-filter-item-text></span>
51+
{% trans "Closed" %}
52+
</li>
53+
{% for f in closed_rounds %}
54+
<li>
55+
<a
56+
data-filter-item-text
57+
{% if f.selected %}
58+
href="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
59+
hx-get="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
60+
{% else %}
61+
href="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
62+
hx-get="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
63+
{% endif %}
64+
hx-push-url="true"
65+
class="flex {% if f.selected %}ps-2 font-medium bg-base-200{% else %}ps-8{% endif %} pe-3 py-2 text-base-content/80 items-center hover:bg-base-200 focus:bg-base-200">
66+
{% if f.selected %}
67+
{% heroicon_mini "check" aria_hidden="true" size=16 class="stroke-2 me-1" %}
68+
{% endif %}
69+
{{ f.title }}
70+
</a>
71+
</li>
72+
{% endfor %}
73+
{% endif %}
7074

71-
{% if open_rounds %}
72-
<div class="overflow-auto max-h-80 divide-y tab-open-rounds"
73-
x-show="tab === 'open_rounds'"
74-
:aria-hidden="tab === 'open_rounds' ? 'false' : 'true'"
75-
role="tabpanel"
76-
>
77-
{% for f in open_rounds %}
78-
<a
79-
data-filter-item-text
80-
{% if f.selected %}
81-
href="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
82-
hx-get="{% url "apply:submissions:list" %}{% remove_from_query "only_query_string" "page" round=f.id %}"
83-
{% else %}
84-
href="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
85-
hx-get="{% url "apply:submissions:list" %}{% add_to_query "only_query_string" "page" round=f.id %}"
86-
{% endif %}
87-
hx-push-url="true"
88-
class="flex {% if f.selected %}ps-2 font-medium{% else %}ps-8{% endif %} pe-3 py-2 text-base-content/80 items-center hover:bg-base-200 focus:bg-base-200{% if f.selected %}bg-base-200{% endif %}">
89-
{% if f.selected %}
90-
{% heroicon_mini "check" aria_hidden="true" size=16 class="stroke-2 me-1" %}
91-
{% endif %}
75+
</ul>
9276

93-
{{ f.title }}
94-
</a>
95-
{% endfor %}
96-
</div>
97-
{% endif %}
98-
</div>
9977
{% else %}
10078
<div class="block py-2 px-3 text-base-content/80">
10179
{% trans "No rounds available" %}
10280
</div>
10381
{% endif %}
10482
</div>
105-
</div>

0 commit comments

Comments
 (0)