summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorTom Carrick <knyght@knyg.ht>2020-05-06 10:29:51 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-05-11 18:16:38 +0200
commitd24ba1be7a53a113d19e2860c03aff9922efec24 (patch)
tree50549f65e023c3ab94db2bc3b902405a58051f40 /django
parentd6aff369ad33457ae2355b5b210faf1c4890ff35 (diff)
Fixed #31034 -- Added a navigation sidebar to the admin.
Co-authored-by: elky <elky@users.noreply.github.com> Co-authored-by: Goetz <goetz.buerkle@gmail.com>
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/sites.py3
-rw-r--r--django/contrib/admin/static/admin/css/base.css21
-rw-r--r--django/contrib/admin/static/admin/css/login.css4
-rw-r--r--django/contrib/admin/static/admin/css/nav_sidebar.css100
-rw-r--r--django/contrib/admin/static/admin/js/nav_sidebar.js22
-rw-r--r--django/contrib/admin/templates/admin/app_list.html40
-rw-r--r--django/contrib/admin/templates/admin/base.html16
-rw-r--r--django/contrib/admin/templates/admin/index.html42
-rw-r--r--django/contrib/admin/templates/admin/login.html2
-rw-r--r--django/contrib/admin/templates/admin/nav_sidebar.html4
-rw-r--r--django/contrib/admin/templates/registration/logged_out.html2
11 files changed, 216 insertions, 40 deletions
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index 116303c94a..5cdb2a0f72 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -50,6 +50,8 @@ class AdminSite:
# URL for the "View site" link at the top of each admin page.
site_url = '/'
+ enable_nav_sidebar = True
+
_empty_value_display = '-'
login_form = None
@@ -309,6 +311,7 @@ class AdminSite:
'has_permission': self.has_permission(request),
'available_apps': self.get_app_list(request),
'is_popup': False,
+ 'is_nav_sidebar_enabled': self.enable_nav_sidebar,
}
def password_change(self, request, extra_context=None):
diff --git a/django/contrib/admin/static/admin/css/base.css b/django/contrib/admin/static/admin/css/base.css
index 8f7472f13b..c4285195fc 100644
--- a/django/contrib/admin/static/admin/css/base.css
+++ b/django/contrib/admin/static/admin/css/base.css
@@ -4,6 +4,10 @@
@import url(fonts.css);
+html, body {
+ height: 100%;
+}
+
body {
margin: 0;
padding: 0;
@@ -732,6 +736,23 @@ table#change-history tbody th {
width: 100%;
min-width: 980px;
padding: 0;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+#container > div {
+ flex-shrink: 0;
+}
+
+#container > .main {
+ display: flex;
+ flex: 1 0 auto;
+}
+
+.main > .content {
+ flex: 1 0;
+ max-width: 100%;
}
#content {
diff --git a/django/contrib/admin/static/admin/css/login.css b/django/contrib/admin/static/admin/css/login.css
index d88249bf28..062b36e051 100644
--- a/django/contrib/admin/static/admin/css/login.css
+++ b/django/contrib/admin/static/admin/css/login.css
@@ -1,7 +1,8 @@
/* LOGIN FORM */
-body.login {
+.login {
background: #f8f8f8;
+ height: auto;
}
.login #header {
@@ -30,6 +31,7 @@ body.login {
width: 28em;
min-width: 300px;
margin: 100px auto;
+ height: auto;
}
.login #content-main {
diff --git a/django/contrib/admin/static/admin/css/nav_sidebar.css b/django/contrib/admin/static/admin/css/nav_sidebar.css
new file mode 100644
index 0000000000..6fcfb26131
--- /dev/null
+++ b/django/contrib/admin/static/admin/css/nav_sidebar.css
@@ -0,0 +1,100 @@
+.sticky {
+ position: sticky;
+ top: 0;
+ max-height: 100vh;
+}
+
+.toggle-nav-sidebar {
+ z-index: 20;
+ left: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 23px;
+ width: 23px;
+ border-right: 1px solid #eaeaea;
+ background-color: #ffffff;
+ cursor: pointer;
+ font-size: 20px;
+ color: #447e9b;
+}
+
+[dir="rtl"] .toggle-nav-sidebar {
+ border-left: 1px solid #eaeaea;
+ border-right: 0;
+}
+
+.toggle-nav-sidebar:hover,
+.toggle-nav-sidebar:focus {
+ background-color: #f6f6f6;
+}
+
+#nav-sidebar {
+ z-index: 15;
+ flex: 0 0 275px;
+ left: -276px;
+ margin-left: -276px;
+ border-top: 1px solid transparent;
+ border-right: 1px solid #eaeaea;
+ background-color: #ffffff;
+ overflow: auto;
+}
+
+[dir="rtl"] #nav-sidebar {
+ border-left: 1px solid #eaeaea;
+ border-right: 0;
+ left: 0;
+ margin-left: 0;
+ right: -276px;
+ margin-right: -276px;
+}
+
+.toggle-nav-sidebar::before {
+ content: '\00BB';
+}
+
+.main.shifted .toggle-nav-sidebar::before {
+ content: '\00AB';
+}
+
+.main.shifted > #nav-sidebar {
+ left: 24px;
+ margin-left: 0;
+}
+
+[dir="rtl"] .main.shifted > #nav-sidebar {
+ left: 0;
+ right: 24px;
+ margin-right: 0;
+}
+
+#nav-sidebar .module th {
+ width: 100%;
+}
+
+#nav-sidebar .module th,
+#nav-sidebar .module caption {
+ padding-left: 16px;
+}
+
+[dir="rtl"] #nav-sidebar .module th,
+[dir="rtl"] #nav-sidebar .module caption {
+ padding-left: 8px;
+ padding-right: 16px;
+}
+
+#nav-sidebar .current-app .section:link,
+#nav-sidebar .current-app .section:visited {
+ color: #ffc;
+ font-weight: bold;
+}
+
+#nav-sidebar .current-model {
+ background: #ffc;
+}
+
+@media (max-width: 767px) {
+ #nav-sidebar, #toggle-nav-sidebar {
+ display: none;
+ }
+}
diff --git a/django/contrib/admin/static/admin/js/nav_sidebar.js b/django/contrib/admin/static/admin/js/nav_sidebar.js
new file mode 100644
index 0000000000..9b558ca2e7
--- /dev/null
+++ b/django/contrib/admin/static/admin/js/nav_sidebar.js
@@ -0,0 +1,22 @@
+'use strict';
+{
+ const toggleNavSidebar = document.getElementById('toggle-nav-sidebar');
+ if (toggleNavSidebar !== null) {
+ const main = document.getElementById('main');
+ let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen');
+ if (navSidebarIsOpen === null) {
+ navSidebarIsOpen = 'true';
+ }
+ main.classList.toggle('shifted', navSidebarIsOpen === 'true');
+
+ toggleNavSidebar.addEventListener('click', function() {
+ if (navSidebarIsOpen == 'true') {
+ navSidebarIsOpen = 'false';
+ } else {
+ navSidebarIsOpen = 'true';
+ }
+ localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen);
+ main.classList.toggle('shifted');
+ });
+ }
+}
diff --git a/django/contrib/admin/templates/admin/app_list.html b/django/contrib/admin/templates/admin/app_list.html
new file mode 100644
index 0000000000..ea4a85bd0b
--- /dev/null
+++ b/django/contrib/admin/templates/admin/app_list.html
@@ -0,0 +1,40 @@
+{% load i18n %}
+
+{% if app_list %}
+ {% for app in app_list %}
+ <div class="app-{{ app.app_label }} module{% if app.app_url in request.path %} current-app{% endif %}">
+ <table>
+ <caption>
+ <a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a>
+ </caption>
+ {% for model in app.models %}
+ <tr class="model-{{ model.object_name|lower }}{% if model.admin_url in request.path %} current-model{% endif %}">
+ {% if model.admin_url %}
+ <th scope="row"><a href="{{ model.admin_url }}"{% if model.admin_url in request.path %} aria-current="page"{% endif %}>{{ model.name }}</a></th>
+ {% else %}
+ <th scope="row">{{ model.name }}</th>
+ {% endif %}
+
+ {% if model.add_url %}
+ <td><a href="{{ model.add_url }}" class="addlink">{% translate 'Add' %}</a></td>
+ {% else %}
+ <td></td>
+ {% endif %}
+
+ {% if model.admin_url and show_changelinks %}
+ {% if model.view_only %}
+ <td><a href="{{ model.admin_url }}" class="viewlink">{% translate 'View' %}</a></td>
+ {% else %}
+ <td><a href="{{ model.admin_url }}" class="changelink">{% translate 'Change' %}</a></td>
+ {% endif %}
+ {% elif show_changelinks %}
+ <td></td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+ {% endfor %}
+{% else %}
+ <p>{% translate 'You don’t have permission to view or edit anything.' %}</p>
+{% endif %}
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
index 8d6425ad04..61b5a13d74 100644
--- a/django/contrib/admin/templates/admin/base.html
+++ b/django/contrib/admin/templates/admin/base.html
@@ -4,6 +4,9 @@
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}">
+{% if not is_popup and is_nav_sidebar_enabled %}
+ <link rel="stylesheet" type="text/css" href="{% static "admin/css/nav_sidebar.css" %}">
+{% endif %}
{% block extrastyle %}{% endblock %}
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}">{% endif %}
{% block extrahead %}{% endblock %}
@@ -64,6 +67,14 @@
{% endblock %}
{% endif %}
+ <div class="main shifted" id="main">
+ {% if not is_popup and is_nav_sidebar_enabled %}
+ {% block nav-sidebar %}
+ {% include "admin/nav_sidebar.html" %}
+ {% endblock %}
+ {% endif %}
+ <div class="content">
+
{% block messages %}
{% if messages %}
<ul class="messagelist">{% for message in messages %}
@@ -86,8 +97,13 @@
<!-- END Content -->
{% block footer %}<div id="footer"></div>{% endblock %}
+ </div>
+ </div>
</div>
<!-- END Container -->
+{% if not is_popup and is_nav_sidebar_enabled %}
+ <script src="{% static 'admin/js/nav_sidebar.js' %}" async></script>
+{% endif %}
</body>
</html>
diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html
index 299c268669..b6e84b64ed 100644
--- a/django/contrib/admin/templates/admin/index.html
+++ b/django/contrib/admin/templates/admin/index.html
@@ -9,47 +9,11 @@
{% block breadcrumbs %}{% endblock %}
+{% block nav-sidebar %}{% endblock %}
+
{% block content %}
<div id="content-main">
-
-{% if app_list %}
- {% for app in app_list %}
- <div class="app-{{ app.app_label }} module">
- <table>
- <caption>
- <a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a>
- </caption>
- {% for model in app.models %}
- <tr class="model-{{ model.object_name|lower }}">
- {% if model.admin_url %}
- <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
- {% else %}
- <th scope="row">{{ model.name }}</th>
- {% endif %}
-
- {% if model.add_url %}
- <td><a href="{{ model.add_url }}" class="addlink">{% translate 'Add' %}</a></td>
- {% else %}
- <td></td>
- {% endif %}
-
- {% if model.admin_url %}
- {% if model.view_only %}
- <td><a href="{{ model.admin_url }}" class="viewlink">{% translate 'View' %}</a></td>
- {% else %}
- <td><a href="{{ model.admin_url }}" class="changelink">{% translate 'Change' %}</a></td>
- {% endif %}
- {% else %}
- <td></td>
- {% endif %}
- </tr>
- {% endfor %}
- </table>
- </div>
- {% endfor %}
-{% else %}
- <p>{% translate 'You don’t have permission to view or edit anything.' %}</p>
-{% endif %}
+ {% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
</div>
{% endblock %}
diff --git a/django/contrib/admin/templates/admin/login.html b/django/contrib/admin/templates/admin/login.html
index 97eb439c84..7a192a4bdf 100644
--- a/django/contrib/admin/templates/admin/login.html
+++ b/django/contrib/admin/templates/admin/login.html
@@ -11,6 +11,8 @@
{% block nav-global %}{% endblock %}
+{% block nav-sidebar %}{% endblock %}
+
{% block content_title %}{% endblock %}
{% block breadcrumbs %}{% endblock %}
diff --git a/django/contrib/admin/templates/admin/nav_sidebar.html b/django/contrib/admin/templates/admin/nav_sidebar.html
new file mode 100644
index 0000000000..84956c1bd1
--- /dev/null
+++ b/django/contrib/admin/templates/admin/nav_sidebar.html
@@ -0,0 +1,4 @@
+<div class="sticky toggle-nav-sidebar" id="toggle-nav-sidebar"></div>
+<nav class="sticky" id="nav-sidebar">
+ {% include 'admin/app_list.html' with app_list=available_apps %}
+</nav>
diff --git a/django/contrib/admin/templates/registration/logged_out.html b/django/contrib/admin/templates/registration/logged_out.html
index 90bb8ee668..460e17eafd 100644
--- a/django/contrib/admin/templates/registration/logged_out.html
+++ b/django/contrib/admin/templates/registration/logged_out.html
@@ -3,6 +3,8 @@
{% block breadcrumbs %}<div class="breadcrumbs"><a href="{% url 'admin:index' %}">{% translate 'Home' %}</a></div>{% endblock %}
+{% block nav-sidebar %}{% endblock %}
+
{% block content %}
<p>{% translate "Thanks for spending some quality time with the Web site today." %}</p>