From 821a85ba04fa889cfd5dfef462a8f8f81db199ca Mon Sep 17 00:00:00 2001
From: Tudor Amariei
Date: Wed, 6 Nov 2024 13:00:41 +0200
Subject: [PATCH] Add an expandable section of voting domains
---
.../components/expandable_voting_domains.html | 30 ++++++++++++
.../ngos_listing_by_voting_domain.html | 2 +-
backend/hub/templates/hub/ngo/list.html | 46 ++++++++++++-------
backend/hub/views.py | 40 +++++++++++-----
backend/static_extras/css/hub.css | 46 +++++++++++++++++++
5 files changed, 135 insertions(+), 29 deletions(-)
create mode 100644 backend/hub/templates/hub/ngo/components/expandable_voting_domains.html
diff --git a/backend/hub/templates/hub/ngo/components/expandable_voting_domains.html b/backend/hub/templates/hub/ngo/components/expandable_voting_domains.html
new file mode 100644
index 0000000..59a50aa
--- /dev/null
+++ b/backend/hub/templates/hub/ngo/components/expandable_voting_domains.html
@@ -0,0 +1,30 @@
+
+
+
+ {{ section_title }} ({{ counters.ngos_accepted }})
+ ❯
+
+
+
+
+
+
+ {% for domain_details in page_obj %}
+
+
+
+ {% endfor %}
+
+
+
+
diff --git a/backend/hub/templates/hub/ngo/components/ngos_listing_by_voting_domain.html b/backend/hub/templates/hub/ngo/components/ngos_listing_by_voting_domain.html
index 8db7c91..3a8754b 100644
--- a/backend/hub/templates/hub/ngo/components/ngos_listing_by_voting_domain.html
+++ b/backend/hub/templates/hub/ngo/components/ngos_listing_by_voting_domain.html
@@ -3,7 +3,7 @@
{% for section_details in page_obj %}
-
+
{{ section_details.domain.name }} ({{ section_details.organizations|length }})
diff --git a/backend/hub/templates/hub/ngo/list.html b/backend/hub/templates/hub/ngo/list.html
index 04af387..8163073 100644
--- a/backend/hub/templates/hub/ngo/list.html
+++ b/backend/hub/templates/hub/ngo/list.html
@@ -17,32 +17,46 @@
value="{{ current_search }}"
aria-label="{% trans 'Search...' %}"
placeholder="{% trans 'Search...' %}">
-
+
+
+
+
-
{% if page_obj %}
-
- {% if VOTING_DOMAIN_ENABLED %}
- {% include "hub/ngo/components/ngos_listing_by_voting_domain.html" %}
- {% else %}
- {% include "hub/ngo/components/ngos_listing.html" %}
- {% endif %}
-
+
+ {% if VOTING_DOMAIN_ENABLED %}
+ {% include "hub/ngo/components/ngos_listing_by_voting_domain.html" %}
+ {% else %}
+ {% include "hub/ngo/components/ngos_listing.html" %}
+ {% endif %}
+
{% include "hub/shared/pagination.html" with page_obj=page_obj domain=current_domain %}
diff --git a/backend/hub/views.py b/backend/hub/views.py
index 9a9f715..1cb7b83 100644
--- a/backend/hub/views.py
+++ b/backend/hub/views.py
@@ -1,4 +1,5 @@
import logging
+import unicodedata
from datetime import datetime
from typing import Dict, List, Optional, Union
from urllib.parse import unquote
@@ -37,6 +38,7 @@
)
from hub.models import (
FLAG_CHOICES,
+ SETTINGS_CHOICES,
BlogPost,
Candidate,
CandidateConfirmation,
@@ -46,7 +48,6 @@
Domain,
FeatureFlag,
Organization,
- SETTINGS_CHOICES,
)
from hub.workers.update_organization import update_organization
@@ -244,24 +245,39 @@ class OrganizationListView(SearchMixin):
paginate_by = 9
template_name = "hub/ngo/list.html"
+ @staticmethod
+ def _filter_letter(char: str) -> bool:
+ if char.isalpha():
+ return True
+ elif char == " ":
+ return True
+
+ return False
+
def group_organizations_by_domain(self, queryset) -> List[Dict[str, Union[Domain, List[Organization]]]]:
organizations_by_domain: Dict[Domain, List[Organization]] = {}
for organization in queryset:
- domain_name: Domain = organization.voting_domain
- if domain_name not in organizations_by_domain:
- organizations_by_domain[domain_name] = []
+ domain: Domain = organization.voting_domain
+ if domain not in organizations_by_domain:
+ organizations_by_domain[domain] = []
- organizations_by_domain[domain_name].append(organization)
+ organizations_by_domain[domain].append(organization)
# dictionary to list of dictionaries
- organizations_by_domain_list = [
- {
- "domain": domain,
- "organizations": sorted(organizations, key=lambda org: org.name),
- }
- for domain, organizations in organizations_by_domain.items()
- ]
+ organizations_by_domain_list = []
+ for domain, organizations in organizations_by_domain.items():
+ snake_case_domain_key = "".join(filter(self._filter_letter, domain.name)).lower().replace(" ", "_")
+ normalized_domain_key = unicodedata.normalize("NFKD", snake_case_domain_key).encode("ascii", "ignore")
+
+ organizations_by_domain_list.append(
+ {
+ "domain": domain,
+ "domain_key": normalized_domain_key.decode("utf-8"),
+ "organizations": sorted(organizations, key=lambda org: org.name),
+ }
+ )
+
organizations_by_domain_list = sorted(organizations_by_domain_list, key=lambda x: x["domain"].pk)
return organizations_by_domain_list
diff --git a/backend/static_extras/css/hub.css b/backend/static_extras/css/hub.css
index 6967221..7ae7224 100644
--- a/backend/static_extras/css/hub.css
+++ b/backend/static_extras/css/hub.css
@@ -669,3 +669,49 @@ hr.tight {
border-color: #ffdd57;
color: #5c4a00;
}
+
+.collapsible-title {
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.active, .collapsible-title:hover {
+ background-color: #ffdd57;
+}
+
+.collapsible-content {
+ padding: 0 18px;
+ display: none;
+ overflow: hidden;
+ background-color: #f1f1f1;
+}
+
+details {
+ user-select: none;
+}
+
+details>summary span.icon {
+ width: 24px;
+ height: 24px;
+ transition: all 0.3s;
+ margin-left: auto;
+ font: inherit;
+ font-size: 1em;
+}
+
+summary span.icon {
+ transform: rotate(90deg);
+}
+
+details[open] summary span.icon {
+ transform: rotate(270deg);
+}
+
+summary {
+ display: flex;
+ cursor: pointer;
+}
+
+summary::-webkit-details-marker {
+ display: none;
+}