diff --git a/README.md b/README.md index 04b89e5..9227cc2 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ ADMIN_SHORTCUTS = [ Where ... -* required `url_name` is a name that will be resolved using Django's reverse url method (see Django docs https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#admin-reverse-urls) +* required `url_name` is a name that will be resolved using Django's reverse url method (see Django docs https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#admin-reverse-urls) * optional `app_name` is the name of the admin app that will be used for URL reversal. You can safely ignore this if you have only one admin site in your ``urls.py`` * optional `url` is a direct link that will override `url_name` * optional `url_extra` is extra stuff to be attached at the end of the url (like GET data for pre-filtering admin views) @@ -63,7 +63,7 @@ Where ... Like above, this function can optionally take one argument `request` as well. * optional `has_perms` is a list of strings representing the built-in admin permissions required to display the shortcut. * optional `open_new_window` sets whether the link should open in a new window (default is False) -* optional `icon` is a Font Awesome Solid https://fontawesome.com/icons?d=gallery&s=solid icon class (if you don't specify one, magical ponies will do it for you) +* optional `icon` is an emoji (if you don't specify one, magical ponies will do it for you) 4) profit!! @@ -71,8 +71,6 @@ Where ... ``` ADMIN_SHORTCUTS_SETTINGS = { - 'show_on_all_pages': False, - 'hide_app_list': False, 'open_new_window': False, } ``` @@ -80,8 +78,6 @@ ADMIN_SHORTCUTS_SETTINGS = { Where ... -* optional `show_on_all_pages` shows the shortcuts on all admin pages -* optional `hide_app_list` collapses the app list * optional `open_new_window` makes all shortcuts open in a new window @@ -113,7 +109,6 @@ ADMIN_SHORTCUTS = [ 'title': 'Add user', 'url_name': 'admin:auth_user_add', 'test_func': 'example.utils.has_perms_to_users', - 'url_name': 'admin:auth_user_add', 'has_perms': 'example.utils.has_perms_to_users', }, ] @@ -128,10 +123,10 @@ ADMIN_SHORTCUTS = [ { 'title': 'Files', 'url_name': 'admin:index', + 'icon': '❤️' }, { 'title': 'Contact forms', - 'icon': 'columns', 'url_name': 'admin:index', 'count_new': '3', }, @@ -148,8 +143,6 @@ ADMIN_SHORTCUTS = [ }, ] ADMIN_SHORTCUTS_SETTINGS = { - 'show_on_all_pages': True, - 'hide_app_list': True, 'open_new_window': False, } ``` @@ -158,5 +151,5 @@ ADMIN_SHORTCUTS_SETTINGS = { ## I want to change how stuff looks * to change the CSS overwrite the ``templates/admin_shortcuts/base.css`` template -* to change the which icons are magically selected specify the mappings in ``ADMIN_SHORTCUTS_CLASS_MAPPINGS`` +* to change the which icons are magically selected specify the mappings in ``ADMIN_SHORTCUTS_ICON_MAPPINGS`` diff --git a/admin_shortcuts/templates/admin/base_site.html b/admin_shortcuts/templates/admin/base_site.html deleted file mode 100644 index d9906d8..0000000 --- a/admin_shortcuts/templates/admin/base_site.html +++ /dev/null @@ -1,31 +0,0 @@ -{% extends "admin/base.html" %} -{% load admin_shortcuts_tags %} - -{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} - -{% block branding %} -

{{ site_header|default:_('Django administration') }}

-{% endblock %} - -{% block nav-global %} - {% block admin_shortcuts %} - {# this closes the #header div #} -
- {% admin_shortcuts %} - {#
don't close this one, because it's closed in base.html #} - {% endblock %} -{% endblock %} - - -{% block extrastyle %} - {{ block.super }} - - - -{% endblock %} - - -{% block extrahead %} - {{ block.super }} - {% admin_shortcuts_js %} -{% endblock %} diff --git a/admin_shortcuts/templates/admin/index.html b/admin_shortcuts/templates/admin/index.html new file mode 100644 index 0000000..ad50c47 --- /dev/null +++ b/admin_shortcuts/templates/admin/index.html @@ -0,0 +1,15 @@ +{% extends "admin/index.html" %} +{% load admin_shortcuts_tags %} + +{% block nav-breadcrumbs %} +
+ {% admin_shortcuts %} +
+ {{ block.super }} +{% endblock %} + + +{% block extrastyle %} + {{ block.super }} + +{% endblock %} diff --git a/admin_shortcuts/templates/admin_shortcuts/base.css b/admin_shortcuts/templates/admin_shortcuts/base.css index 7568618..aef1dc5 100644 --- a/admin_shortcuts/templates/admin_shortcuts/base.css +++ b/admin_shortcuts/templates/admin_shortcuts/base.css @@ -1,5 +1,5 @@ {% block main %}{% endblock %} {% block count %}{% endblock %} -{% block advanced %}{% endblock %} {% block icons %}{% endblock %} +{% block dark_mode %}{% endblock %} {% block extra %}{% endblock %} \ No newline at end of file diff --git a/admin_shortcuts/templates/admin_shortcuts/base.html b/admin_shortcuts/templates/admin_shortcuts/base.html index b768695..6b2abce 100644 --- a/admin_shortcuts/templates/admin_shortcuts/base.html +++ b/admin_shortcuts/templates/admin_shortcuts/base.html @@ -1,7 +1,6 @@ {% load i18n %} {% if enable_admin_shortcuts %} - {% if admin_shortcuts %} {% endif %} - - {% if enable_hide_app_list %} -   {% trans 'Advanced' %}   - {% endif %} - {% endif %} \ No newline at end of file diff --git a/admin_shortcuts/templates/admin_shortcuts/js.html b/admin_shortcuts/templates/admin_shortcuts/js.html deleted file mode 100644 index 0c91fc6..0000000 --- a/admin_shortcuts/templates/admin_shortcuts/js.html +++ /dev/null @@ -1,16 +0,0 @@ -{% load admin_shortcuts_tags %} -{% if enable_hide_app_list %} - - - -{% endif %} \ No newline at end of file diff --git a/admin_shortcuts/templates/admin_shortcuts/shortcut.html b/admin_shortcuts/templates/admin_shortcuts/shortcut.html index 38015af..1e13b00 100644 --- a/admin_shortcuts/templates/admin_shortcuts/shortcut.html +++ b/admin_shortcuts/templates/admin_shortcuts/shortcut.html @@ -1,5 +1,5 @@ - {% if shortcut.icon %}{% endif %} + {% if shortcut.icon %}{{ shortcut.icon }}{% endif %} {% if shortcut.title %}{{ shortcut.title }}{% endif %} {% if shortcut.count != None %}{{ shortcut.count }}{% endif %} {% if shortcut.count_new %}{{ shortcut.count_new }}{% endif %} diff --git a/admin_shortcuts/templates/admin_shortcuts/style.css b/admin_shortcuts/templates/admin_shortcuts/style.css index 8d9f727..9451380 100644 --- a/admin_shortcuts/templates/admin_shortcuts/style.css +++ b/admin_shortcuts/templates/admin_shortcuts/style.css @@ -3,43 +3,165 @@ {% block main %} /* shortcuts */ -.admin_shortcuts .shortcuts { background: #50839e; padding: 10px 40px 20px; margin: 0; list-style: none; - box-shadow: 0 2px 5px rgba(0,0,0,0.2) inset; } -@media (max-width: 1024px) { .admin_shortcuts .shortcuts { padding-left: 30px; padding-right: 30px; } } -.admin_shortcuts .shortcuts ul:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; - height: 0; } -.admin_shortcuts .shortcuts ul { padding: 0; margin: 5px 0 0 0; list-style: none; } -.admin_shortcuts .shortcuts h2 { color: #fff; border-bottom: 1px solid #6093ae; line-height: 24px; margin: 10px 0 5px; } -.admin_shortcuts .shortcuts li { padding: 0; margin: 0; float: left; list-style: none; } -.admin_shortcuts .shortcuts li a { padding: 20px 0px 20px 55px; margin: 5px 10px 5px 0; display: block; float: left; - color: #fff; border: 1px solid #6b9db9; background: #6093ae 10px 50% no-repeat; font-size: 14px; line-height: 14px; - border-radius: 3px; box-shadow: 1px 1px 3px rgba(0,0,0,0.1); position: relative; min-height: 14px; } -.admin_shortcuts .shortcuts li a .title { text-shadow: 0 0 1px rgba(0,0,0,0.5); padding-right: 25px; } -.admin_shortcuts .shortcuts li a:hover, .admin_shortcuts .shortcuts li a:focus { background-color: #6b9db9; } -.admin_shortcuts .shortcuts li a:active { background-color: #50839e; border-color: #6093ae; } +.admin_shortcuts .shortcuts { + padding: 10px 40px 10px 40px; + margin: 0; + list-style: none; +} + +@media (max-width: 1024px) { + .admin_shortcuts .shortcuts { + padding-left: 20px; + padding-right: 20px; + } +} + +.admin_shortcuts .shortcuts ul:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} + +.admin_shortcuts .shortcuts ul { + padding: 0; + margin: 5px 0 0 0; + list-style: none; +} + +.admin_shortcuts .shortcuts h2 { + font-weight: normal; + color: #666; + line-height: 24px; + margin: 10px 0 5px; +} + +.admin_shortcuts .shortcuts li { + padding: 0; + margin: 0; + float: left; + list-style: none; +} + +.admin_shortcuts .shortcuts li a { + padding: 20px 0px 20px 55px; + margin: 5px 10px 5px 0; + display: block; + float: left; + color: #666; + border: 1px solid #ddd; + background: #fff; + font-size: 14px; + line-height: 14px; + border-radius: 4px; + position: relative; + min-height: 14px; + transition: none; +} + +.admin_shortcuts .shortcuts li a .title { + padding-right: 25px; +} + +.admin_shortcuts .shortcuts li a:hover, .admin_shortcuts .shortcuts li a:focus, .admin_shortcuts .shortcuts li a:active { + border-color: #888; + color: #333; + text-decoration: none; +} {% endblock %} + {% block count %} /* count */ -.admin_shortcuts .shortcuts li a .count { position: absolute; right: 3px; bottom: 2px; color: #96c9e5; font-size: 10px; } -.admin_shortcuts .shortcuts li a .count_new { position: absolute; right: -7px; top: -7px; color: #fff; font-size: 11px; - line-height: 14px; border-radius: 30px; display: block; overflow: hidden; max-width: 60px; min-width: 15px; - height: 20px; padding: 5px 5px 0 5px; background: #940f3a; text-align: center; font-weight: bold; - box-shadow: 0 0 3px rgba(0,0,0,0.2); } -{% endblock %} +.admin_shortcuts .shortcuts li a .count { + position: absolute; + right: 3px; + bottom: 2px; + color: #aaa; + font-size: 10px; +} -{% block advanced %} -/* advanced button */ -.admin_shortcuts #toggle_app_list { display: block; text-align: center; padding: 2px 0; color: #fff; font-size: 11px; - font-weight: bold; background: #79aec8; } -.admin_shortcuts #toggle_app_list:hover { text-decoration: none; } -.admin_shortcuts #toggle_app_list .closed { display: inline; } -.admin_shortcuts #toggle_app_list .open { display: none; } -.admin_shortcuts #toggle_app_list.open .open { display: inline; } -.admin_shortcuts #toggle_app_list.open .closed { display: none; } +.admin_shortcuts .shortcuts li a .count_new { + position: absolute; + right: -7px; + top: -7px; + color: #fff; + font-size: 11px; + line-height: 14px; + border-radius: 30px; + display: block; + overflow: hidden; + max-width: 60px; + min-width: 15px; + height: 20px; + padding: 5px 5px 0 5px; + background: #940f3a; + text-align: center; + font-weight: bold; +} {% endblock %} + {% block icons %} /* icons */ -.admin_shortcuts .shortcuts li a .icon { width: 34px; height: 32px; text-align: center; font-size: 24px; line-height: 32px; position: absolute; left: 10px; top: 10px; color: rgba(255,255,255,0.8); } +.admin_shortcuts .shortcuts li a .icon { + width: 34px; + height: 32px; + text-align: center; + font-size: 24px; + line-height: 32px; + position: absolute; + left: 10px; + top: 10px; +} +{% endblock %} + + +{% block dark_mode %} +@media (prefers-color-scheme: dark) { + .admin_shortcuts .shortcuts li a { + background: #333; + color: #ccc; + border-color: #444; + } + .admin_shortcuts .shortcuts li a:hover, .admin_shortcuts .shortcuts li a:focus, .admin_shortcuts .shortcuts li a:active { + border-color: #888; + color: #fff; + } +} +@media (prefers-color-scheme: light) { + .admin_shortcuts .shortcuts li a { + background: #fff; + color: #666; + border-color: #ddd; + } + .admin_shortcuts .shortcuts li a:hover, .admin_shortcuts .shortcuts li a:focus, .admin_shortcuts .shortcuts li a:active { + border-color: #888; + color: #333; + } +} +html[data-theme="dark"] { + .admin_shortcuts .shortcuts li a { + background: #333; + color: #ccc; + border-color: #444; + } + .admin_shortcuts .shortcuts li a:hover, .admin_shortcuts .shortcuts li a:focus, .admin_shortcuts .shortcuts li a:active { + border-color: #888; + color: #fff; + } +} +html[data-theme="light"] { + .admin_shortcuts .shortcuts li a { + background: #fff; + color: #666; + border-color: #ddd; + } + .admin_shortcuts .shortcuts li a:hover, .admin_shortcuts .shortcuts li a:focus, .admin_shortcuts .shortcuts li a:active { + border-color: #888; + color: #333; + } +} {% endblock %} diff --git a/admin_shortcuts/templatetags/admin_shortcuts_tags.py b/admin_shortcuts/templatetags/admin_shortcuts_tags.py index 987680c..f176e52 100644 --- a/admin_shortcuts/templatetags/admin_shortcuts_tags.py +++ b/admin_shortcuts/templatetags/admin_shortcuts_tags.py @@ -112,8 +112,7 @@ def admin_shortcuts(context): is_front_page = reverse('admin:index') == request.path return { - 'enable_admin_shortcuts': is_front_page or admin_shortcuts_settings.get('show_on_all_pages'), - 'enable_hide_app_list': is_front_page and admin_shortcuts_settings.get('hide_app_list'), + 'enable_admin_shortcuts': is_front_page, 'admin_shortcuts': admin_shortcuts, } @@ -123,18 +122,6 @@ def admin_shortcuts_css(): return {} -@register.inclusion_tag('admin_shortcuts/js.html', takes_context=True) -def admin_shortcuts_js(context): - admin_shortcuts_settings = getattr(settings, 'ADMIN_SHORTCUTS_SETTINGS', {}) - request = context.get('request', None) - is_front_page = False - if request: - is_front_page = reverse('admin:index') == request.path - return { - 'enable_hide_app_list': is_front_page and admin_shortcuts_settings.get('hide_app_list'), - } - - def eval_func(func_path, request): try: module_str = '.'.join(func_path.split('.')[:-1]) @@ -163,14 +150,14 @@ def admin_static_url(): return getattr(settings, 'ADMIN_MEDIA_PREFIX', None) or ''.join([settings.STATIC_URL, 'admin/']) -DEFAULT_ICON = getattr(settings, 'ADMIN_SHORTCUTS_DEFAULT_ICON', 'cog') +DEFAULT_ICON = getattr(settings, 'ADMIN_SHORTCUTS_DEFAULT_ICON', '➡️') def get_shortcut_class(text=''): text = text.lower() icon_weights = {} max_weight = 0 - for icon, keywords in CLASS_MAPPINGS.items(): + for icon, keywords in ICON_MAPPINGS.items(): weight = sum([1 if k in text else 0 for k in keywords]) icon_weights[icon] = weight if weight > max_weight: @@ -184,23 +171,84 @@ def get_shortcut_class(text=''): return DEFAULT_ICON -CLASS_MAPPINGS = getattr(settings, 'ADMIN_SHORTCUTS_CLASS_MAPPINGS', { - 'home': ['home'], - 'plus': ['add'], - 'lock': ['logout', 'login'], - 'file': ['file'], - 'file-alt': ['page', 'text'], - 'image': ['image', 'picture', 'photo', 'gallery'], - 'shopping-cart': ['product', 'store'], - 'money-bill-alt': ['order', 'pay', 'sale', 'income', 'revenue'], - 'archive': ['category'], - 'user': ['user', 'account'], - 'users': ['group', 'team'], - 'address-book': ['address', 'contacts'], - 'envelope': ['message', 'contact', 'mail'], - 'folder': ['folder', 'directory', 'path'], - 'book': ['blog', 'book'], - 'calendar': ['event', 'calendar'], - 'truck': ['delivery', 'shipping'], - 'edit': ['change', 'edit'], +ICON_MAPPINGS = getattr(settings, 'ADMIN_SHORTCUTS_ICON_MAPPINGS', { + '🏠': ['home', 'main', 'dashboard', 'start'], + '➕': ['add', 'plus', 'create', 'new'], + '🔒': ['logout', 'login', 'lock', 'secure', 'authentication'], + '📄': ['file', 'document', 'paper', 'doc'], + '📃': ['page', 'text', 'sheet'], + '🖼️': ['image', 'picture', 'photo', 'gallery', 'media'], + '🛒': ['product', 'store', 'cart', 'shopping'], + '💵': ['order', 'pay', 'sale', 'income', 'revenue', 'money', 'finance'], + '📦': ['category', 'box', 'package'], + '👤': ['user', 'account', 'profile', 'person'], + '👥': ['group', 'team', 'users', 'community'], + '📒': ['address', 'contacts', 'book', 'directory'], + '✉️': ['message', 'contact', 'mail', 'email'], + '📁': ['folder', 'directory', 'path', 'files'], + '📚': ['blog', 'book', 'library', 'reading'], + '📅': ['event', 'calendar', 'schedule', 'date'], + '🚚': ['delivery', 'shipping', 'truck', 'transport'], + '✏️': ['change', 'edit', 'modify', 'write', 'pencil'], + '🔍': ['search', 'find', 'look', 'magnify'], + '📊': ['report', 'chart', 'statistics', 'analytics', 'data', 'graph'], + '💼': ['business', 'portfolio', 'briefcase', 'work'], + '📈': ['growth', 'increase', 'analytics', 'rise', 'trend'], + '⚙️': ['settings', 'preferences', 'gear', 'tools'], + '📉': ['decrease', 'decline', 'drop', 'reduce'], + '🔗': ['link', 'connection', 'url', 'chain'], + '📷': ['camera', 'photo', 'picture', 'snap'], + '🔔': ['notification', 'alert', 'bell', 'reminder'], + '🏷️': ['tag', 'label', 'price', 'sticker'], + '💬': ['chat', 'conversation', 'message', 'discussion', 'comment', 'feedback', 'reply'], + '🔄': ['sync', 'refresh', 'reload', 'update'], + '💡': ['idea', 'tip', 'insight', 'lightbulb'], + '🔓': ['unlock', 'access', 'open', 'secure'], + '📌': ['pin', 'bookmark', 'save', 'mark'], + '🔧': ['tool', 'fix', 'maintenance', 'repair', 'wrench'], + '🖊️': ['sign', 'signature', 'write', 'pen'], + '📤': ['send', 'outbox', 'upload', 'export'], + '📥': ['receive', 'inbox', 'download', 'import'], + '🗑️': ['delete', 'remove', 'trash', 'discard'], + '📋': ['clipboard', 'copy', 'list', 'paste'], + '🔨': ['build', 'construct', 'hammer'], + '💳': ['payment', 'credit card', 'card', 'finance'], + '🔑': ['key', 'password', 'authentication', 'security'], + '📝': ['note', 'document', 'write', 'memo', 'to-do', 'task', 'list'], + '🗂️': ['archive', 'file', 'folder', 'organize'], + '💻': ['computer', 'laptop', 'device', 'tech'], + '📲': ['mobile', 'phone', 'device', 'smartphone'], + '🌐': ['web', 'internet', 'global', 'world'], + '🕒': ['time', 'clock', 'hour', 'schedule'], + '🔋': ['battery', 'power', 'charge'], + '🛠️': ['tools', 'repair', 'settings', 'maintenance'], + '📶': ['network', 'signal', 'wifi', 'connection'], + '🎨': ['design', 'art', 'creativity', 'paint'], + '📛': ['badge', 'identification', 'ID', 'tag'], + '🎫': ['ticket', 'pass', 'entry'], + '🌟': ['favorite', 'highlight', 'star', 'feature'], + '🗳️': ['vote', 'ballot', 'election', 'choice'], + '📎': ['attachment', 'paperclip', 'clip'], + '📧': ['email', 'message', 'mail', 'send'], + '📬': ['mailbox', 'receive', 'post', 'inbox'], + '📯': ['announcement', 'notification', 'alert'], + '📱': ['mobile', 'phone', 'smartphone', 'device'], + '🖥️': ['desktop', 'computer', 'monitor', 'screen'], + '🖨️': ['print', 'printer', 'document'], + '🖱️': ['click', 'mouse', 'pointer'], + '🎙️': ['record', 'microphone', 'audio'], + '🎥': ['video', 'camera', 'record', 'film'], + '🎞️': ['film', 'movie', 'record'], + '🎬': ['action', 'movie', 'clapperboard'], + '📹': ['video', 'camera', 'record'], + '🎧': ['audio', 'headphones', 'music'], + '🎤': ['microphone', 'audio', 'record'], + '📡': ['satellite', 'antenna', 'signal'], + '🛰️': ['satellite', 'space', 'signal'], + '📺': ['tv', 'television', 'screen'], + '📻': ['radio', 'audio', 'broadcast'], + '📽️': ['projector', 'film', 'movie'], + '🔦': ['flashlight', 'light', 'torch'], + '📖': ['book', 'read', 'pages'], + '📰': ['news', 'newspaper', 'article'], }) diff --git a/example/django-admin-shortcuts-screenshot.png b/example/django-admin-shortcuts-screenshot.png new file mode 100644 index 0000000..253d31a Binary files /dev/null and b/example/django-admin-shortcuts-screenshot.png differ diff --git a/example/example/settings.py b/example/example/settings.py index 0fd23c2..5c5bbde 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -131,6 +131,7 @@ # Admin Shortcuts + ADMIN_SHORTCUTS = [ { 'shortcuts': [ @@ -156,6 +157,7 @@ 'title': 'Add user', 'url_name': 'admin:auth_user_add', 'test_func': 'example.utils.has_perms_to_users', + 'has_perms': 'example.utils.has_perms_to_users', }, ] }, @@ -169,10 +171,10 @@ { 'title': 'Files', 'url_name': 'admin:index', + 'icon': '❤️' }, { 'title': 'Contact forms', - 'icon': 'columns', 'url_name': 'admin:index', 'count_new': '3', }, @@ -181,7 +183,7 @@ 'url_name': 'admin:index', }, { - 'title': _('Orders'), + 'title': 'Orders', 'url_name': 'admin:index', 'count_new': '12', }, @@ -189,7 +191,5 @@ }, ] ADMIN_SHORTCUTS_SETTINGS = { - 'show_on_all_pages': True, - 'hide_app_list': True, 'open_new_window': False, } diff --git a/example/example/utils.py b/example/example/utils.py index b7ea495..7a75462 100644 --- a/example/example/utils.py +++ b/example/example/utils.py @@ -10,4 +10,4 @@ def count_groups(): def has_perms_to_users(request): - return request.user.is_authenticated and request.user.is_superuser + return request.user.is_authenticated and request.user.is_staff diff --git a/setup.py b/setup.py index a796c96..f746b42 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ packages=find_packages(exclude=['docs', 'tests*']), include_package_data=True, install_requires=[ - 'Django>=1.2', + 'Django>=5.0', ], download_url='https://github.com/alesdotio/django-admin-shortcuts/tarball/' + version, license='BSD',