From 09d11365233a50bd5b768e4412ef4c1679ae7162 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 24 Oct 2019 10:15:47 +0200
Subject: [PATCH 2/2] pages: add navigation buttons on page view (#12437)

---
 combo/manager/static/css/combo.manager.css   | 30 +++++++++++++++--
 combo/manager/templates/combo/page_view.html | 17 ++++++++++
 combo/manager/views.py                       |  7 ++++
 tests/test_manager.py                        | 34 ++++++++++++++++++--
 4 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/combo/manager/static/css/combo.manager.css b/combo/manager/static/css/combo.manager.css
index e9cc94e..0043904 100644
--- a/combo/manager/static/css/combo.manager.css
+++ b/combo/manager/static/css/combo.manager.css
@@ -132,8 +132,6 @@ div.cell-list .empty-cell {
 	margin-left: 2em;
 }
 
-.icon-eye-open:before             { content: "\f06e "; }
-
 div.objects-list {
 	clear: both;
 }
@@ -195,6 +193,34 @@ p#redirection {
 .icon-eye-open:before { content: "\f06e "; }
 .icon-edit:before { content: "\f044"; }
 
+div.navigation ul,
+div.navigation li {
+	margin: 0;
+	padding: 0;
+	list-style: none;
+	line-height: 150%;
+}
+
+div.navigation li::before {
+	content: "";
+	font-family: FontAwesome;
+	display: inline-block;
+	width: 2em;
+	text-align: center;
+}
+
+div.navigation li.nav-left::before {
+	content: "\f053";  /* chevron-left */
+}
+
+div.navigation li.nav-right::before {
+	content: "\f054";  /* chevron-right */
+}
+
+div.navigation li.nav-up::before {
+	content: "\f077";  /* chevron-up */
+}
+
 #assets-browser {
 	display: flex;
 }
diff --git a/combo/manager/templates/combo/page_view.html b/combo/manager/templates/combo/page_view.html
index 83646bc..8fc17e4 100644
--- a/combo/manager/templates/combo/page_view.html
+++ b/combo/manager/templates/combo/page_view.html
@@ -84,6 +84,23 @@
 
 </div>
 
+{% if object.parent_id or previous_page or next_page %}
+<div class="page-options navigation">
+<h3>{% trans 'Navigation' %}</h3>
+<ul>
+{% if object.parent_id %}
+<li class="nav-up"><a href="{% url 'combo-manager-page-view' pk=object.parent_id %}">{{ object.parent.title }}</a></li>
+{% endif %}
+{% if previous_page %}
+<li class="nav-left"><a href="{% url 'combo-manager-page-view' pk=previous_page.pk %}">{{ previous_page.title }}</a></li>
+{% endif %}
+{% if next_page %}
+<li class="nav-right"><a href="{% url 'combo-manager-page-view' pk=next_page.pk %}">{{ next_page.title }}</a></li>
+{% endif %}
+</ul>
+</div>
+{% endif %}
+
 </aside>
 {% endblock %} {# sidebar #}
 
diff --git a/combo/manager/views.py b/combo/manager/views.py
index 6b051ba..f514f2b 100644
--- a/combo/manager/views.py
+++ b/combo/manager/views.py
@@ -255,8 +255,15 @@ class PageView(DetailView):
             placeholders.append(placeholder_dict)
 
         context['placeholders'] = placeholders
+
+        context.update({
+            'previous_page': self.object.get_previous_page(check_visibility=False),
+            'next_page': self.object.get_next_page(check_visibility=False),
+        })
+
         return context
 
+
 page_view = requires_csrf_token(PageView.as_view())
 
 
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 136e8f9..8340463 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -208,6 +208,30 @@ def test_page_placeholder_restricted_visibility(app, admin_user):
     assert 'foobar' in resp.text
 
 
+def test_edit_page_navigation(app, admin_user):
+    page1 = Page.objects.create(title='One', slug='one', parent=None, template_name='standard')
+    page2 = Page.objects.create(title='Two', slug='two', parent=page1, template_name='standard')
+    page3 = Page.objects.create(title='Three', slug='three', parent=page1, template_name='standard')
+    page4 = Page.objects.create(title='Four', slug='four', parent=None, template_name='standard')
+
+    app = login(app)
+
+    resp = app.get('/manage/pages/%s/' % page1.pk)
+    assert '<li class="nav-up"' not in resp.text
+    assert '<li class="nav-left"' not in resp.text
+    assert '<li class="nav-right"><a href="/manage/pages/%s/">%s</a></li>' % (page2.pk, page2.title) in resp.text
+
+    resp = app.get('/manage/pages/%s/' % page2.pk)
+    assert '<li class="nav-up"><a href="/manage/pages/%s/">%s</a></li>' % (page1.pk, page1.title) in resp.text
+    assert '<li class="nav-left"><a href="/manage/pages/%s/">%s</a></li>' % (page1.pk, page1.title) in resp.text
+    assert '<li class="nav-right"><a href="/manage/pages/%s/">%s</a></li>' % (page3.pk, page3.title) in resp.text
+
+    resp = app.get('/manage/pages/%s/' % page4.pk)
+    assert '<li class="nav-up"' not in resp.text
+    assert '<li class="nav-left"><a href="/manage/pages/%s/">%s</a></li>' % (page3.pk, page3.title) in resp.text
+    assert '<li class="nav-right"' not in resp.text
+
+
 def test_delete_page(app, admin_user):
     Page.objects.all().delete()
     page = Page(title='One', slug='one', template_name='standard')
@@ -1027,6 +1051,7 @@ def test_menu_json(app, admin_user):
     assert resp.headers['content-type'] == 'application/javascript'
     assert resp.text.startswith('fooBar([{"')
 
+
 def test_page_multiple_link_cells(app, admin_user):
     Page.objects.all().delete()
     page = Page(title='One', slug='one', template_name='standard')
@@ -1039,9 +1064,12 @@ def test_page_multiple_link_cells(app, admin_user):
     patched_orig = Page.get_as_reordered_flat_hierarchy
     app = login(app)
     with mock.patch('combo.data.models.Page.get_as_reordered_flat_hierarchy') as func:
-        func.return_value = []
-        resp = app.get('/manage/pages/%s/' % page.id)
-        assert func.call_count == 1
+        func.side_effect = lambda *args, **kwargs: patched_orig(*args, **kwargs)
+        app.get('/manage/pages/%s/' % page.id)
+        # only 1 call for combo.data.forms.get_page_choices
+        # 1 call for get_previous_page and 1 call for get_next_page
+        assert func.call_count == 3
+
 
 def test_page_cell_placeholder(app, admin_user):
     page = Page(title='One', slug='one', template_name='standard')
-- 
2.20.1

