Navbar (#31)
* started workin on 'navbar' module * changed bootstrap theme to bootswatch/Simplex * big work on navbar logic * starting creating menus using navbar * converted app views to new Wepage decorator, updated navbar * reimplemented DernieresMaraudes as a dropdown instead of ContextMixin * reorganised static files, minor code cleanups * turned Link.href into lazy-evaluated property * collapsed 'navbar' module into 'website', dynamic building of ApplicationMenu subclasses * minor cleanup * blah blah blah * added way to add admin/non-admin links * minor style change : red border for active page instead of all dropdowns * deleted file * prepare adding removing menu templates files, being replaced by code * essayé de généraliser le code pour les modaux bootstrap, non testé git status * more preparation and thinking on navbar app_menus logic... * added LinkManager and DropdownManager, getting closer... * small fix in DropdownManager.__get__ * boosted up work: keep it simple so it can be merged fast, major layout changes * added month filter on maraudes:liste * added 'as_icon' filter to display boolean/null values as bootstrap icons * remove inactive user from planning selection * removed all unused 'menu' templates * set up django_select2 to use static files * small fix after review
This commit is contained in:
102
website/navbar.py
Normal file
102
website/navbar.py
Normal file
@@ -0,0 +1,102 @@
|
||||
""" Draft for navbar application menu
|
||||
"""
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
registered = []
|
||||
|
||||
|
||||
class Link:
|
||||
""" Navbar link
|
||||
|
||||
Constructor takes one required argument :
|
||||
- text : text to display for the link
|
||||
|
||||
and two optional arguments :
|
||||
- target : str or tuple (str, dict)
|
||||
- icon : bootstrap icon name, no validation
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, text, target="#", icon=None):
|
||||
self.text = text
|
||||
self._target = target
|
||||
self.icon = icon
|
||||
|
||||
@property
|
||||
def href(self):
|
||||
""" Lazy creation of html 'href' value, using 'target' instance attribute """
|
||||
if not hasattr(self, '_href'):
|
||||
if self._target == "#": #Create void link
|
||||
self._href = "#"
|
||||
else:
|
||||
try:
|
||||
target, kwargs = self._target
|
||||
except ValueError:
|
||||
target = self._target
|
||||
kwargs = {}
|
||||
assert type(target) == str
|
||||
assert type(kwargs) == dict
|
||||
self._href = reverse(target, **kwargs)
|
||||
return self._href
|
||||
|
||||
|
||||
|
||||
class LinkManager:
|
||||
""" Per-class manager of links """
|
||||
|
||||
def __init__(self):
|
||||
self.items = []
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
if instance: #Filtering done at each call, not optimized at all !
|
||||
if not instance.user.is_superuser:
|
||||
return [link for link in self.items if link.admin_link == False]
|
||||
else:
|
||||
return self.items.copy()
|
||||
return self
|
||||
|
||||
def add(self, link):
|
||||
self.items.append(link)
|
||||
|
||||
def __repr__(self):
|
||||
return '<LinkManager: [' + ', '.join((l.text for l in self.items)) + ']>'
|
||||
|
||||
|
||||
|
||||
class MenuRegistry(type):
|
||||
""" Metaclass that registers subclass into module level variable 'registered' """
|
||||
def __new__(metacls, name, bases, attrs):
|
||||
cls = type.__new__(metacls, name, bases, attrs)
|
||||
if name != "ApplicationMenu":
|
||||
print('registering menu', cls)
|
||||
registered.append(cls)
|
||||
# Create Link instance for header attributes
|
||||
try:
|
||||
header, target, icon = cls.header
|
||||
except ValueError:
|
||||
header = cls.header
|
||||
target = "#"
|
||||
icon = None
|
||||
cls.header = Link(header, target, icon)
|
||||
cls.links = LinkManager()
|
||||
return cls
|
||||
|
||||
|
||||
|
||||
class ApplicationMenu(metaclass=MenuRegistry):
|
||||
name = None
|
||||
header = None
|
||||
|
||||
def __init__(self, view, user):
|
||||
self.view = view
|
||||
self.user = user
|
||||
self.is_active = self.name == self.view.app_name
|
||||
|
||||
@classmethod
|
||||
def add_link(cls, link, admin=False):
|
||||
if not isinstance(link, Link):
|
||||
link = Link(*link)
|
||||
link.admin_link = admin
|
||||
cls.links.add(link)
|
||||
|
||||
Reference in New Issue
Block a user