Use dict instead of custom object to represent menus

as prep for editing menu config directly in app
This commit is contained in:
Lance Edgar 2022-02-23 00:26:14 -06:00
parent 0c5992ad75
commit 3553f23eab
3 changed files with 63 additions and 63 deletions

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2021 Lance Edgar # Copyright © 2010-2022 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -26,38 +26,11 @@ App Menus
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from rattail.core import Object import re
from rattail.util import import_module_path from rattail.util import import_module_path
class MenuGroup(Object):
title = None
items = None
is_menu = True
is_link = False
class MenuItem(Object):
title = None
url = None
target = None
is_link = True
is_menu = False
is_sep = False
class MenuItemMenu(Object):
title = None
items = None
is_menu = True
is_sep = False
class MenuSeparator(object):
is_menu = False
is_sep = True
def make_simple_menus(request): def make_simple_menus(request):
""" """
Build the main menu list for the app. Build the main menu list for the app.
@ -93,30 +66,48 @@ def make_simple_menus(request):
for subitem in item['items']: for subitem in item['items']:
if subitem['allowed']: if subitem['allowed']:
submenu_items.append(make_menu_entry(subitem)) submenu_items.append(make_menu_entry(subitem))
menu_items.append(MenuItemMenu( menu_items.append({
title=item['title'], 'type': 'submenu',
items=submenu_items)) 'title': item['title'],
'items': submenu_items,
'is_menu': True,
'is_sep': False,
})
elif item.get('type') == 'sep': elif item.get('type') == 'sep':
# we only want to add a sep, *if* we already have some # we only want to add a sep, *if* we already have some
# menu items (i.e. there is something to separate) # menu items (i.e. there is something to separate)
# *and* the last menu item is not a sep (avoid doubles) # *and* the last menu item is not a sep (avoid doubles)
if menu_items and not menu_items[-1].is_sep: if menu_items and not menu_items[-1]['is_sep']:
menu_items.append(make_menu_entry(item)) menu_items.append(make_menu_entry(item))
else: # standard menu item else: # standard menu item
menu_items.append(make_menu_entry(item)) menu_items.append(make_menu_entry(item))
# remove final separator if present # remove final separator if present
if menu_items and menu_items[-1].is_sep: if menu_items and menu_items[-1]['is_sep']:
menu_items.pop() menu_items.pop()
# only add if we wound up with something # only add if we wound up with something
assert menu_items assert menu_items
if menu_items: if menu_items:
final_menus.append(MenuGroup( group = {
title=topitem['title'], 'type': 'menu',
items=menu_items)) 'key': topitem.get('key'),
'title': topitem['title'],
'items': menu_items,
'is_menu': True,
'is_link': False,
}
# topitem w/ no key likely means it did not come
# from config but rather explicit definition in
# code. so we are free to "invent" a (safe) key
# for it, since that is only for editing config
if not group['key']:
group['key'] = re.sub(r'\W', '', topitem['title'].lower())
final_menus.append(group)
return final_menus return final_menus
@ -128,13 +119,22 @@ def make_menu_entry(item):
""" """
# separator # separator
if item.get('type') == 'sep': if item.get('type') == 'sep':
return MenuSeparator() return {
'type': 'sep',
'is_menu': False,
'is_sep': True,
}
# standard menu item # standard menu item
return MenuItem( return {
title=item['title'], 'type': 'item',
url=item['url'], 'title': item['title'],
target=item.get('target')) 'url': item['url'],
'target': item.get('target'),
'is_link': True,
'is_menu': False,
'is_sep': False,
}
def is_allowed(request, item): def is_allowed(request, item):

View file

@ -4,16 +4,16 @@
% for topitem in menus: % for topitem in menus:
<li> <li>
% if topitem.is_link: % if topitem['is_link']:
${h.link_to(topitem.title, topitem.url, target=topitem.target)} ${h.link_to(topitem['title'], topitem['url'], target=topitem['target'])}
% else: % else:
<a>${topitem.title}</a> <a>${topitem['title']}</a>
<ul> <ul>
% for subitem in topitem.items: % for subitem in topitem['items']:
% if subitem.is_sep: % if subitem['is_sep']:
<li>-</li> <li>-</li>
% else: % else:
<li>${h.link_to(subitem.title, subitem.url, target=subitem.target)}</li> <li>${h.link_to(subitem['title'], subitem['url'], target=subitem['target'])}</li>
% endif % endif
% endfor % endfor
</ul> </ul>

View file

@ -200,33 +200,33 @@
<div class="navbar-start"> <div class="navbar-start">
% for topitem in menus: % for topitem in menus:
% if topitem.is_link: % if topitem['is_link']:
${h.link_to(topitem.title, topitem.url, target=topitem.target, class_='navbar-item')} ${h.link_to(topitem['title'], topitem['url'], target=topitem['target'], class_='navbar-item')}
% else: % else:
<div class="navbar-item has-dropdown is-hoverable"> <div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">${topitem.title}</a> <a class="navbar-link">${topitem['title']}</a>
<div class="navbar-dropdown"> <div class="navbar-dropdown">
% for item in topitem.items: % for item in topitem['items']:
% if item.is_menu: % if item['is_menu']:
<% item_hash = id(item) %> <% item_hash = id(item) %>
<% toggle = 'menu_{}_shown'.format(item_hash) %> <% toggle = 'menu_{}_shown'.format(item_hash) %>
<div> <div>
<a class="navbar-link" @click.prevent="toggleNestedMenu('${item_hash}')"> <a class="navbar-link" @click.prevent="toggleNestedMenu('${item_hash}')">
${item.title} ${item['title']}
</a> </a>
</div> </div>
% for subitem in item.items: % for subitem in item['items']:
% if subitem.is_sep: % if subitem['is_sep']:
<hr class="navbar-divider" v-show="${toggle}"> <hr class="navbar-divider" v-show="${toggle}">
% else: % else:
${h.link_to("{}".format(subitem.title), subitem.url, class_='navbar-item nested', target=subitem.target, **{'v-show': toggle})} ${h.link_to("{}".format(subitem['title']), subitem['url'], class_='navbar-item nested', target=subitem['target'], **{'v-show': toggle})}
% endif % endif
% endfor % endfor
% else: % else:
% if item.is_sep: % if item['is_sep']:
<hr class="navbar-divider"> <hr class="navbar-divider">
% else: % else:
${h.link_to(item.title, item.url, class_='navbar-item', target=item.target)} ${h.link_to(item['title'], item['url'], class_='navbar-item', target=item['target'])}
% endif % endif
% endif % endif
% endfor % endfor
@ -705,9 +705,9 @@
## declare nested menu visibility toggle flags ## declare nested menu visibility toggle flags
% for topitem in menus: % for topitem in menus:
% if topitem.is_menu: % if topitem['is_menu']:
% for item in topitem.items: % for item in topitem['items']:
% if item.is_menu: % if item['is_menu']:
WholePageData.menu_${id(item)}_shown = false WholePageData.menu_${id(item)}_shown = false
% endif % endif
% endfor % endfor