feat: Enhances navigation with collapsible menus

Introduces NavCollapse to manage grouped navigation items.
Simplifies 'features.py' by organizing items under collapsible sections.
Updates HTML generation for both NavItem and NavCollapse classes.

Improves user experience by improving sidebar organization.
This commit is contained in:
Kumi 2024-11-19 06:56:52 +01:00
parent ca2f3eda3a
commit 7f79a79a17
Signed by: kumi
GPG key ID: ECBCC9082395383F
4 changed files with 97 additions and 35 deletions

View file

@ -1,4 +1,4 @@
from frontend.classes import NavSection, NavItem, DashboardSection from frontend.classes import NavSection, NavItem, NavCollapse, DashboardSection
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -6,14 +6,20 @@ from django.urls import reverse_lazy
dreams_section = NavSection("Dreams") dreams_section = NavSection("Dreams")
dreams_items = { dreams_settings_collapse = NavCollapse("Settings", icon="fas fa-fw fa-cog")
"dreams_dream_list": NavItem("Dream List", reverse_lazy("dreams:dream_list")),
"dreams_theme_list": NavItem("Themes", reverse_lazy("dreams:theme_list")),
"dreams_notification_list": NavItem("Notifications", reverse_lazy("dreams:notification_list"))
}
for _, item in dreams_items.items(): dream_list = NavItem("Dream List", reverse_lazy("dreams:dream_list"))
dreams_section.add_item(item)
dreams_settings = [
NavItem("Themes", reverse_lazy("dreams:theme_list")),
NavItem("Notifications", reverse_lazy("dreams:notification_list")),
]
for item in dreams_settings:
dreams_settings_collapse.add_item(item)
dreams_section.add_item(dream_list)
dreams_section.add_item(dreams_settings_collapse)
NAV_SECTIONS = [dreams_section] NAV_SECTIONS = [dreams_section]

View file

@ -1,16 +1,18 @@
from django.template.loader import render_to_string from django.template.loader import render_to_string
import random
class NavSection: class NavSection:
def __init__(self, name, order=100): def __init__(self, name, order=100):
self.name = name self.name = name
self.order = order self.order = order
self.items = [] self.items: list[NavItem | NavCollapse] = []
def add_item(self, item): def add_item(self, item):
self.items.append(item) self.items.append(item)
def get_html(self, active=None): def get_html(self, active=None) -> str:
html = f""" html = f"""
<!-- Heading --> <!-- Heading -->
<div class="sidebar-heading">{self.name}</div> <div class="sidebar-heading">{self.name}</div>
@ -19,19 +21,7 @@ class NavSection:
self.items.sort(key=lambda x: x.order) self.items.sort(key=lambda x: x.order)
for item in self.items: for item in self.items:
html += ( html += item.get_html()
"""
<!-- Nav Item -->
<li class="nav-item"""
+ (" active" if item.name == active else "")
+ f"""">
<a class="nav-link" href="{item.url}">
<i class="{item.icon}"></i>
<span>{item.name}</span>
</a>
</li>
"""
)
return html return html
@ -44,6 +34,64 @@ class NavItem:
self.title = title or name self.title = title or name
self.order = order self.order = order
def get_html(self, active=None) -> str:
return f"""
<!-- Nav Item -->
<li class="nav-item">
<a class="nav-link{" active" if self.name == active else ""}" href="{self.url}">
<i class="{self.icon}"></i>
<span>{self.name}</span>
</a>
</li>
"""
class NavCollapse:
def __init__(self, name, icon="fas fa-fw fa-smile", order=100):
self.name = name
self.icon = icon
self.order = order
self.items: list[NavItem] = []
def add_item(self, item):
self.items.append(item)
def get_html(self, active=None) -> str:
element_id = random.randint(1000, 9999)
html = f"""
<!-- Nav Item - {self.name} -->
<li class="nav-item">
<a class="nav-link collapsed" href="#" data-toggle="collapse" data-target="#collapse{element_id}" aria-expanded="true" aria-controls="collapse{element_id}">
<i class="{self.icon}"></i>
<span>{self.name}</span>
</a>
<div id="collapse{element_id}" class="collapse" aria-labelledby="heading{element_id}" data-parent="#accordionSidebar">
<div class="bg-white py-2 collapse-inner rounded">
"""
self.items.sort(key=lambda x: x.order)
for item in self.items:
html += (
"""
<a class="collapse-item"""
+ (" active" if item.name == active else "")
+ f""""
href="{item.url}">
<i class="{item.icon}"></i>
{item.name}</a>
"""
)
html += """
</div>
</div>
</li>
"""
return html
class DashboardSection: class DashboardSection:
def __init__(self, name, template, context=None): def __init__(self, name, template, context=None):

View file

@ -2,13 +2,15 @@ from django import template
from django.conf import settings from django.conf import settings
from django.urls import reverse_lazy from django.urls import reverse_lazy
from ..classes import NavSection
from importlib import import_module from importlib import import_module
register = template.Library() register = template.Library()
@register.simple_tag @register.simple_tag
def sidebar_nav(): def sidebar_nav():
sections = [] sections: list[NavSection] = []
for module in settings.CORE_MODULES + settings.ENABLED_MODULES: for module in settings.CORE_MODULES + settings.ENABLED_MODULES:
try: try:

View file

@ -1,4 +1,4 @@
from frontend.classes import NavSection, NavItem, DashboardSection from frontend.classes import NavSection, NavItem, NavCollapse, DashboardSection
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -6,18 +6,24 @@ from django.urls import reverse_lazy
mood_section = NavSection("Mood") mood_section = NavSection("Mood")
mood_items = { mood_settings_collapse = NavCollapse("Settings", icon="fas fa-fw fa-cog")
"mood_status_list": NavItem("Status List", reverse_lazy("mood:status_list")),
"mood_activity_list": NavItem("Activities", reverse_lazy("mood:activity_list")), mood_status_list = NavItem("Status List", reverse_lazy("mood:status_list"))
"mood_mood_list": NavItem("Moods", reverse_lazy("mood:mood_list")),
"mood_notification_list": NavItem( mood_settings = [
NavItem("Activities", reverse_lazy("mood:activity_list")),
NavItem("Moods", reverse_lazy("mood:mood_list")),
NavItem(
"Notifications", reverse_lazy("mood:notification_list") "Notifications", reverse_lazy("mood:notification_list")
), ),
"mood_statistics": NavItem("Statistics", reverse_lazy("mood:statistics")), NavItem("Statistics", reverse_lazy("mood:statistics")),
} ]
for _, item in mood_items.items(): for setting in mood_settings:
mood_section.add_item(item) mood_settings_collapse.add_item(setting)
mood_section.add_item(mood_status_list)
mood_section.add_item(mood_settings_collapse)
NAV_SECTIONS = [mood_section] NAV_SECTIONS = [mood_section]