From 26514e60fb92df3ee94af993b87e43c438ee5f3d Mon Sep 17 00:00:00 2001 From: Adam Goldsmith Date: Tue, 6 Feb 2024 00:41:01 -0500 Subject: [PATCH] dashboard: Add more flexible Link Card dashboard fragment with support for tooltips and accordions --- dashboard/__init__.py | 20 +++++++++++ .../templates/dashboard/dashboard.dj.html | 8 ++++- .../templates/dashboard/links_card.dj.html | 33 ++++++++++++++---- doorcontrol/dashboard.py | 16 ++++----- membershipworks/dashboard.py | 34 +++++++++++-------- paperwork/dashboard.py | 30 ++++++++++------ rentals/dashboard.py | 9 ++--- 7 files changed, 104 insertions(+), 46 deletions(-) diff --git a/dashboard/__init__.py b/dashboard/__init__.py index e54b45e..3f5a70a 100644 --- a/dashboard/__init__.py +++ b/dashboard/__init__.py @@ -1,3 +1,4 @@ +import dataclasses from typing import Any from django.http import HttpRequest @@ -10,6 +11,16 @@ def register(fragment): return fragment +@dataclasses.dataclass +class Link: + text: str + href: str + tooltip: str | None = None + body: str | None = None + _: dataclasses.KW_ONLY + permission: str | None + + class DashboardFragment: name: str template: str @@ -18,3 +29,12 @@ class DashboardFragment: def __init__(self, request: HttpRequest): self.request = request + + +class LinksCardDashboardFragment(DashboardFragment): + template = "dashboard/links_card.dj.html" + links: [Link] = [] + + @property + def context(self): + return {"links": self.links} diff --git a/dashboard/templates/dashboard/dashboard.dj.html b/dashboard/templates/dashboard/dashboard.dj.html index b799b9d..dce1b4c 100644 --- a/dashboard/templates/dashboard/dashboard.dj.html +++ b/dashboard/templates/dashboard/dashboard.dj.html @@ -16,7 +16,7 @@
{{ app }}
- {% include app_dash.template with ctx=app_dash.context %} + {% include app_dash.template with app=app ctx=app_dash.context %}
{% endif %} @@ -24,3 +24,9 @@ {% endblock %} +{% block script %} + +{% endblock %} diff --git a/dashboard/templates/dashboard/links_card.dj.html b/dashboard/templates/dashboard/links_card.dj.html index 4dc8ca6..f41475b 100644 --- a/dashboard/templates/dashboard/links_card.dj.html +++ b/dashboard/templates/dashboard/links_card.dj.html @@ -1,7 +1,28 @@ - + diff --git a/doorcontrol/dashboard.py b/doorcontrol/dashboard.py index baf7d2b..121a5ff 100644 --- a/doorcontrol/dashboard.py +++ b/doorcontrol/dashboard.py @@ -1,20 +1,20 @@ -from typing import Any - import dashboard +from dashboard import Link from .views import REPORTS @dashboard.register -class DoorControlDashboardFragment(dashboard.DashboardFragment): +class DoorControlDashboardFragment(dashboard.LinksCardDashboardFragment): name = "Door Controls" - template = "dashboard/links_card.dj.html" @property - def context(self) -> Any: - return { - "links": dict(rt for report in REPORTS for rt in report._report_types()) - } + def links(self) -> list[Link]: + return [ + Link(name, link, permission="doorcontrol.view_hidevent") + for report in REPORTS + for name, link in report._report_types() + ] @property def visible(self) -> bool: diff --git a/membershipworks/dashboard.py b/membershipworks/dashboard.py index e02ecac..f454acb 100644 --- a/membershipworks/dashboard.py +++ b/membershipworks/dashboard.py @@ -1,25 +1,31 @@ -from typing import Any - from django.urls import reverse import dashboard +from dashboard import Link @dashboard.register -class MembershipworksDashboardFragment(dashboard.DashboardFragment): +class MembershipworksDashboardFragment(dashboard.LinksCardDashboardFragment): name = "MembershipWorks" - template = "dashboard/links_card.dj.html" - @property - def context(self) -> Any: - links = {} - - if self.request.user.has_perm("membershipworks.view_event"): - links["Upcoming Events"] = reverse("membershipworks:upcoming-events") - links["Event Report"] = reverse("membershipworks:event-index-report") - links["Event Attendees"] = reverse("membershipworks:event-attendees") - - return {"links": links} + links = [ + Link( + "Upcoming Events", + reverse("membershipworks:upcoming-events"), + permission="membershipworks.view_event", + tooltip="Generator for Wordpress posts", + ), + Link( + "Event Report", + reverse("membershipworks:event-index-report"), + permission="membershipworks.view_event", + ), + Link( + "Event Attendees", + reverse("membershipworks:event-attendees"), + permission="membershipworks.view_event", + ), + ] @property def visible(self) -> bool: diff --git a/paperwork/dashboard.py b/paperwork/dashboard.py index 67f840f..8c0901b 100644 --- a/paperwork/dashboard.py +++ b/paperwork/dashboard.py @@ -1,37 +1,45 @@ -from typing import Any - from django.urls import reverse import dashboard +from dashboard import Link from membershipworks.models import Member from .models import Department @dashboard.register -class PaperworkDashboardFragment(dashboard.DashboardFragment): +class PaperworkDashboardFragment(dashboard.LinksCardDashboardFragment): name = "Paperwork" - template = "dashboard/links_card.dj.html" @property - def context(self) -> Any: - links = {} + def links(self) -> list[Link]: + links = [] member = Member.from_user(self.request.user) if member is not None: - links["Member Certifications"] = reverse( - "paperwork:member_certifications", kwargs={"uid": member.uid} + links.append( + dashboard.Link( + "Member Certifications", + reverse( + "paperwork:member_certifications", kwargs={"uid": member.uid} + ), + permission=None, + ) ) if self.request.user.is_superuser or ( member is not None and Department.objects.filter_by_shop_lead(member).exists() ): - links["Department Certifications"] = reverse( - "paperwork:department_certifications" + links.append( + Link( + "Department Certifications", + reverse("paperwork:department_certifications"), + permission=None, + ) ) - return {"links": links} + return links @property def visible(self) -> bool: diff --git a/rentals/dashboard.py b/rentals/dashboard.py index 47abea2..76622fc 100644 --- a/rentals/dashboard.py +++ b/rentals/dashboard.py @@ -1,15 +1,12 @@ -from typing import Any - from django.urls import reverse import dashboard +from dashboard import Link @dashboard.register -class RentalsDashboardFragment(dashboard.DashboardFragment): +class RentalsDashboardFragment(dashboard.LinksCardDashboardFragment): name = "Rentals" template = "dashboard/links_card.dj.html" - @property - def context(self) -> Any: - return {"links": {"Locker Index": reverse("rentals:index")}} + links = [Link("Locker Index", reverse("rentals:index"), permission=None)]