From 3ba39c37c1d7026ffa0d49f86a9266d43aa684a1 Mon Sep 17 00:00:00 2001 From: FinnStutzenstein Date: Fri, 26 Jan 2018 14:56:42 +0100 Subject: [PATCH] Agenda DOCX export, motion log message when comment edited, motion sequential number in detail view and PDF, save pagination state to session storage (fixes #3558). --- CHANGELOG | 3 + openslides/agenda/static/js/agenda/docx.js | 84 ++++++++++++++++++ openslides/agenda/static/js/agenda/site.js | 16 ++-- .../static/templates/agenda/item-list.html | 21 +++-- .../agenda/static/templates/docx/agenda.docx | Bin 0 -> 6899 bytes openslides/agenda/urls.py | 9 ++ openslides/agenda/views.py | 9 ++ .../assignments/static/js/assignments/site.js | 14 ++- .../assignments/assignment-list.html | 17 ++-- openslides/core/apps.py | 2 + openslides/core/static/js/core/site.js | 41 +++++++++ .../mediafiles/static/js/mediafiles/list.js | 11 +-- .../templates/mediafiles/mediafile-list.html | 15 ++-- openslides/motions/static/js/motions/base.js | 8 ++ openslides/motions/static/js/motions/pdf.js | 8 +- openslides/motions/static/js/motions/site.js | 15 ++-- .../templates/motions/motion-detail.html | 5 +- .../static/templates/motions/motion-list.html | 15 ++-- openslides/motions/views.py | 30 ++++--- openslides/urls.py | 1 + openslides/users/static/js/users/site.js | 28 ++---- .../static/templates/users/user-import.html | 18 ++-- .../static/templates/users/user-list.html | 15 ++-- openslides/utils/views.py | 17 +++- tests/integration/motions/test_viewset.py | 32 ++++++- 25 files changed, 320 insertions(+), 114 deletions(-) create mode 100644 openslides/agenda/static/js/agenda/docx.js create mode 100644 openslides/agenda/static/templates/docx/agenda.docx create mode 100644 openslides/agenda/urls.py diff --git a/CHANGELOG b/CHANGELOG index a5cfacd01..c09196ef0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ Agenda: - New permission for managing lists of speakers [#3366]. - Fixed multiple request on creation of agenda related items [#3341]. - Added possibility to mark speakers [#3570]. +- New DOCX export of agenda [#3569]. Motions: - New export dialog [#3185]. @@ -56,6 +57,8 @@ Motions: - Combined all boolean filters into one dropdown menu and added a filter for amendments [#3501]. - Allow to delete own motions [#3516]. +- Log which comment was updated [#3569]. +- Save pagination sate to session storage [#3569]. Elections: - Added pagination for list view [#3393]. diff --git a/openslides/agenda/static/js/agenda/docx.js b/openslides/agenda/static/js/agenda/docx.js new file mode 100644 index 000000000..1de1c92cb --- /dev/null +++ b/openslides/agenda/static/js/agenda/docx.js @@ -0,0 +1,84 @@ +(function () { + +'use strict'; + +angular.module('OpenSlidesApp.agenda.docx', ['OpenSlidesApp.core.docx']) + +.factory('AgendaDocxExport', [ + '$http', + 'gettextCatalog', + 'FileSaver', + 'Agenda', + 'AgendaTree', + 'Config', + function ($http, gettextCatalog, FileSaver, Agenda, AgendaTree, Config) { + + var getData = function (items) { + // Item structure: The top layer has subitems, that are flat. + // The first layer is bold and all sublayers not. The docx + // templater cannot render items recursively, so the second + // layer are all subitems flated out. Spacing is done with tabs. + var tree = AgendaTree.getTree(items); + var subitems = []; // This will be used as a temporary variable. + var flatSubitems = function (children, parentCount) { + _.forEach(children, function (child) { + var taps = _.repeat('\t', parentCount - 1); + subitems.push({ + item_number: taps + child.item.item_number, + item_title: child.item.list_view_title, + }); + flatSubitems(child.children, parentCount + 1); + }); + }; + var twoLayerTree = _.map(tree, function (mainItem) { + subitems = []; + flatSubitems(mainItem.children, 1); + return { + item_number: mainItem.item.item_number, + item_title: mainItem.item.list_view_title, + subitems: subitems, + }; + }); + + // header + var headerline1 = [ + Config.translate(Config.get('general_event_name').value), + Config.translate(Config.get('general_event_description').value) + ].filter(Boolean).join(' – '); + var headerline2 = [ + Config.get('general_event_location').value, + Config.get('general_event_date').value + ].filter(Boolean).join(', '); + + // Data structure for the docx templater. + return { + header: [headerline1, headerline2].join('\n'), + agenda_translation: gettextCatalog.getString('Agenda'), + top_list: twoLayerTree, + }; + }; + + return { + export: function (items) { + // TODO: use filtered items. + var filename = gettextCatalog.getString('Agenda') + '.docx'; + $http.get('/agenda/docxtemplate/').then(function (success) { + var content = window.atob(success.data); + var doc = new Docxgen(content); + + var data = getData(items); + doc.setData(data); + doc.render(); + + var zip = doc.getZip(); + //zip = converter.updateZipFile(zip); + + var out = zip.generate({type: 'blob'}); + FileSaver.saveAs(out, filename); + }); + }, + }; + } +]); + +})(); diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index 262908fd8..cf29def52 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -7,6 +7,7 @@ angular.module('OpenSlidesApp.agenda.site', [ 'OpenSlidesApp.core.pdf', 'OpenSlidesApp.agenda.pdf', 'OpenSlidesApp.agenda.csv', + 'OpenSlidesApp.agenda.docx', ]) .config([ @@ -100,12 +101,14 @@ angular.module('OpenSlidesApp.agenda.site', [ 'gettextCatalog', 'gettext', 'osTableFilter', + 'osTablePagination', 'AgendaCsvExport', 'AgendaPdfExport', + 'AgendaDocxExport', 'ErrorMessage', function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm, AgendaTree, Projector, ProjectionDefault, gettextCatalog, gettext, osTableFilter, - AgendaCsvExport, AgendaPdfExport, ErrorMessage) { + osTablePagination, AgendaCsvExport, AgendaPdfExport, AgendaDocxExport, ErrorMessage) { // Bind agenda tree to the scope $scope.$watch(function () { return Agenda.lastModified(); @@ -167,13 +170,7 @@ angular.module('OpenSlidesApp.agenda.site', [ }; // pagination - $scope.currentPage = 1; - $scope.itemsPerPage = 25; - $scope.limitBegin = 0; - $scope.pageChanged = function() { - $scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage; - $scope.gotoTop(); - }; + $scope.pagination = osTablePagination.createInstance('AgendaTablePagination'); // parse duration for inline editing $scope.generateDurationText = function (item) { @@ -288,6 +285,9 @@ angular.module('OpenSlidesApp.agenda.site', [ $scope.csvExport = function () { AgendaCsvExport.export($scope.itemsFiltered); }; + $scope.docxExport = function () { + AgendaDocxExport.export($scope.itemsFiltered); + }; /** select mode functions **/ $scope.isSelectMode = false; diff --git a/openslides/agenda/static/templates/agenda/item-list.html b/openslides/agenda/static/templates/agenda/item-list.html index 02688c2a2..6e974c87c 100644 --- a/openslides/agenda/static/templates/agenda/item-list.html +++ b/openslides/agenda/static/templates/agenda/item-list.html @@ -111,6 +111,12 @@ CSV +
  • + + + DOCX + +
  • @@ -143,9 +149,10 @@ -
    +
    - Page {{ currentPage }} / {{ Math.ceil(itemsFiltered.length/itemsPerPage) }} + Page {{ pagination.currentPage }} / + {{ Math.ceil(itemsFiltered.length/pagination.itemsPerPage) }}
    @@ -225,7 +232,7 @@ | osFilter: filter.filterString : filter.getObjectQueryString | filter: {closed: filter.booleanFilters.closed.value} | filter: {is_hidden: filter.booleanFilters.is_hidden.value}) - | limitTo : itemsPerPage : limitBegin"> + | limitTo : pagination.itemsPerPage : pagination.limitBegin">
    @@ -368,11 +375,11 @@