From 6b7073fad35f06a051850992a56b75125235c834 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Mon, 25 Feb 2019 09:39:02 +0100
Subject: [PATCH] views: move ods export next to other visualisation actions
 (#30865)

---
 bijoe/static/css/bijoe.css               |  6 -----
 bijoe/templates/bijoe/cube.html          |  3 ---
 bijoe/templates/bijoe/visualization.html |  1 +
 bijoe/visualization/urls.py              |  1 +
 bijoe/visualization/views.py             | 31 +++++++++++++-----------
 5 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/bijoe/static/css/bijoe.css b/bijoe/static/css/bijoe.css
index 4f32625..f340358 100644
--- a/bijoe/static/css/bijoe.css
+++ b/bijoe/static/css/bijoe.css
@@ -72,12 +72,6 @@ select {
   justify-content: space-around; 
 }
 
-/* put ODS export export slightly on the right of the repesentation header */
-#ods {
-  margin: 1ex;
-  top: -2ex;
-}
-
 /* Main content */
 
 /* size main content to let some place on the right for the form */
diff --git a/bijoe/templates/bijoe/cube.html b/bijoe/templates/bijoe/cube.html
index 469235b..6ab49d9 100644
--- a/bijoe/templates/bijoe/cube.html
+++ b/bijoe/templates/bijoe/cube.html
@@ -26,9 +26,6 @@
 {% block content %}
   <form class="cube-form" method="post" action=".">
     {% csrf_token %}
-    {% if visualization %}
-       <input type="submit" value="ODS" name="ods" id="ods"/>
-    {% endif %}
     <h3>Représentation</h3>
     {% include "bijoe/field.html" with field=form.representation %}
     <h3>Répétition</h3>
diff --git a/bijoe/templates/bijoe/visualization.html b/bijoe/templates/bijoe/visualization.html
index 0e5d74b..df56fb5 100644
--- a/bijoe/templates/bijoe/visualization.html
+++ b/bijoe/templates/bijoe/visualization.html
@@ -15,6 +15,7 @@
 {% block actions %}
   <a rel="popup" class="button" href="{% url "rename-visualization" pk=object.pk %}">{% trans "Rename" %}</a>
   <a rel="popup" class="button" href="{% url "delete-visualization" pk=object.pk %}">{% trans "Delete" %}</a>
+  <a rel="popup" class="button" href="{% url "visualization-ods" pk=object.pk %}">{% trans "Export as ODS" %}</a>
   <a href="{{ iframe_url }}" class="button">{% trans "URL for IFRAME" %}</a>
 {% endblock %}
 
diff --git a/bijoe/visualization/urls.py b/bijoe/visualization/urls.py
index 8ac409e..d55313b 100644
--- a/bijoe/visualization/urls.py
+++ b/bijoe/visualization/urls.py
@@ -33,6 +33,7 @@ urlpatterns = [
     url(r'(?P<pk>\d+)/json/$', views.visualization_json, name='visualization-json'),
     url(r'(?P<pk>\d+)/geojson/$', views.visualization_geojson, name='visualization-geojson'),
     url(r'(?P<pk>\d+)/iframe/$', views.visualization_iframe, name='visualization-iframe'),
+    url(r'(?P<pk>\d+)/ods/$', views.visualization_ods, name='visualization-ods'),
     url(r'(?P<pk>\d+)/rename/$', views.rename_visualization, name='rename-visualization'),
     url(r'(?P<pk>\d+)/delete/$', views.delete_visualization, name='delete-visualization'),
 ]
diff --git a/bijoe/visualization/views.py b/bijoe/visualization/views.py
index a771582..2c922ca 100644
--- a/bijoe/visualization/views.py
+++ b/bijoe/visualization/views.py
@@ -18,6 +18,7 @@ import hashlib
 import json
 
 from django.conf import settings
+from django.utils.text import slugify
 from django.views.generic.edit import CreateView, DeleteView, UpdateView
 from django.views.generic.list import MultipleObjectMixin
 from django.views.generic import DetailView, ListView, View, TemplateView
@@ -81,18 +82,7 @@ class CubeMixin(object):
         return super(CubeMixin, self).dispatch(request, *args, **kwargs)
 
 
-class ODSMixin(object):
-    def ods(self, visualization):
-        if not self.visualization:
-            raise Http404
-        response = HttpResponse(content_type='application/vnd.oasis.opendocument.spreadsheet')
-        response['Content-Disposition'] = 'attachment; filename=%s.ods' % self.cube.name
-        workbook = visualization.ods()
-        workbook.save(response)
-        return response
-
-
-class CubeView(views.AuthorizationMixin, CubeDisplayMixin, ODSMixin, CubeMixin, TemplateView):
+class CubeView(views.AuthorizationMixin, CubeDisplayMixin, CubeMixin, TemplateView):
     template_name = 'bijoe/cube.html'
 
     def post(self, request, *args, **kwargs):
@@ -124,8 +114,7 @@ class CreateVisualizationView(views.AuthorizationMixin, CubeMixin, CreateView):
         return super(CreateVisualizationView, self).form_valid(form)
 
 
-class VisualizationView(views.AuthorizationMixin, ODSMixin, CubeDisplayMixin,
-                        DetailView):
+class VisualizationView(views.AuthorizationMixin, CubeDisplayMixin, DetailView):
     model = models.Visualization
     template_name = 'bijoe/visualization.html'
 
@@ -238,6 +227,19 @@ class CubeIframeView(CubeView):
     template_name = 'bijoe/cube_raw.html'
 
 
+class VisualizationODSView(DetailView):
+    model = models.Visualization
+
+    def get(self, request, *args, **kwargs):
+        instance = self.get_object()
+        visualization = Visualization.from_json(instance.parameters, request=request)
+        response = HttpResponse(content_type='application/vnd.oasis.opendocument.spreadsheet')
+        response['Content-Disposition'] = 'attachment; filename=%s.ods' % slugify(instance.name)
+        workbook = visualization.ods()
+        workbook.save(response)
+        return response
+
+
 class VisualizationGeoJSONView(generics.GenericAPIView):
     permission_classes = ()
     queryset = models.Visualization.objects.all()
@@ -288,6 +290,7 @@ visualization = VisualizationView.as_view()
 visualization_iframe = xframe_options_exempt(VisualizationIframeView.as_view())
 visualization_geojson = VisualizationGeoJSONView.as_view()
 visualization_json = VisualizationJSONView.as_view()
+visualization_ods = VisualizationODSView.as_view()
 
 cube_iframe.mellon_no_passive = True
 visualization_iframe.mellon_no_passive = True
-- 
2.20.1

