From 3d264683ff0e553d652553b50d308e317032edc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Sch=C3=BCtze?= Date: Mon, 20 Nov 2017 16:40:39 +0100 Subject: [PATCH] Assignment improvements - Use ckeditor for assignment description field (e.g. for candidatures using html). - Use 2 decimal places for percentage of voting results (motions/assignments) - Allow css style attributes 'float' and 'padding'. - Remove progress bar in election result slide to get more space (height) for candidate rows. --- openslides/assignments/serializers.py | 11 ++++++ .../assignments/static/js/assignments/base.js | 2 +- .../assignments/static/js/assignments/site.js | 10 ++++- .../assignments/assignment-detail.html | 4 +- .../assignments/slide_assignment.html | 39 +++++++------------ openslides/core/static/css/projector.css | 2 +- openslides/core/static/js/core/base.js | 4 +- openslides/motions/static/js/motions/base.js | 2 +- openslides/utils/validate.py | 2 +- 9 files changed, 40 insertions(+), 36 deletions(-) diff --git a/openslides/assignments/serializers.py b/openslides/assignments/serializers.py index a78c9ac1e..9feac5635 100644 --- a/openslides/assignments/serializers.py +++ b/openslides/assignments/serializers.py @@ -12,6 +12,7 @@ from openslides.utils.rest_api import ( ValidationError, ) +from ..utils.validate import validate_html from .models import ( Assignment, AssignmentOption, @@ -209,6 +210,11 @@ class AssignmentFullSerializer(ModelSerializer): 'tags',) validators = (posts_validator,) + def validate(self, data): + if 'description' in data: + data['description'] = validate_html(data['description']) + return data + class AssignmentShortSerializer(AssignmentFullSerializer): """ @@ -231,3 +237,8 @@ class AssignmentShortSerializer(AssignmentFullSerializer): 'agenda_item_id', 'tags',) validators = (posts_validator,) + + def validate(self, data): + if 'description' in data: + data['description'] = validate_html(data['description']) + return data diff --git a/openslides/assignments/static/js/assignments/base.js b/openslides/assignments/static/js/assignments/base.js index d9b4c3bc7..b92c0e100 100644 --- a/openslides/assignments/static/js/assignments/base.js +++ b/openslides/assignments/static/js/assignments/base.js @@ -71,7 +71,7 @@ angular.module('OpenSlidesApp.assignments', []) var skipPercents = config === 'YES_NO' && vote.value === 'Abstain'; if (base && !skipPercents) { - percentNumber = Math.round(vote.weight * 100 / base * 10) / 10; + percentNumber = Math.round(vote.weight * 100 / base * 100) / 100; percentStr = "(" + percentNumber + "%)"; } votes.push({ diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index 8a0da0c43..71a870f5e 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -96,11 +96,13 @@ angular.module('OpenSlidesApp.assignments.site', [ .factory('AssignmentForm', [ 'gettextCatalog', 'operator', + 'Editor', + 'Mediafile', 'Tag', 'Assignment', 'Agenda', 'AgendaTree', - function (gettextCatalog, operator, Tag, Assignment, Agenda, AgendaTree) { + function (gettextCatalog, operator, Editor, Mediafile, Tag, Assignment, Agenda, AgendaTree) { return { // ngDialog for assignment form getDialog: function (assignment) { @@ -117,6 +119,7 @@ angular.module('OpenSlidesApp.assignments.site', [ }, // angular-formly fields for assignment form getFormFields: function (isCreateForm) { + var images = Mediafile.getAllImages(); var formFields = [ { key: 'title', @@ -128,9 +131,12 @@ angular.module('OpenSlidesApp.assignments.site', [ }, { key: 'description', - type: 'textarea', + type: 'editor', templateOptions: { label: gettextCatalog.getString('Description') + }, + data: { + ckeditorOptions: Editor.getOptions(images) } }, { diff --git a/openslides/assignments/static/templates/assignments/assignment-detail.html b/openslides/assignments/static/templates/assignments/assignment-detail.html index ca82c57e6..b441a726e 100644 --- a/openslides/assignments/static/templates/assignments/assignment-detail.html +++ b/openslides/assignments/static/templates/assignments/assignment-detail.html @@ -77,10 +77,10 @@

Description

-
{{ assignment.description }}
+
-
+

Candidates

diff --git a/openslides/assignments/static/templates/assignments/slide_assignment.html b/openslides/assignments/static/templates/assignments/slide_assignment.html index b4d700348..00f7bc750 100644 --- a/openslides/assignments/static/templates/assignments/slide_assignment.html +++ b/openslides/assignments/static/templates/assignments/slide_assignment.html @@ -9,12 +9,13 @@
-
- {{ assignment.description }} +
-
+

Candidates

  • @@ -33,45 +34,31 @@ + -
    Candidates - VotesVotes
    + - {{ option.candidate.get_full_name() }} + {{ option.candidate.get_full_name() }} - +
    - {{ votes[0].label | translate }}: {{ votes[0].value }} · - {{ votes[1].label | translate }}: {{ votes[1].value }} · - {{ votes[2].label | translate }}: {{ votes[2].value }} + {{ votes[0].label | translate }}: {{ votes[0].value }} {{ votes[0].percentStr }}
    + {{ votes[1].label | translate }}: {{ votes[1].value }} {{ votes[1].percentStr }}
    + {{ votes[2].label | translate }}: {{ votes[2].value }} {{ votes[2].percentStr }} - {{ votes[0].label | translate }}: {{ votes[0].value }} · - {{ votes[1].label | translate }}: {{ votes[1].value }} - - - {{votes[0].percentNumber}} % - - - {{votes[1].percentNumber}} % - - - {{votes[2].percentNumber}} % - - + {{ votes[0].label | translate }}: {{ votes[0].value }} {{ votes[0].percentStr }}
    + {{ votes[1].label | translate }}: {{ votes[1].value }} {{ votes[1].percentStr }}
    {{ vote.value }} {{ vote.percentStr }} -
    - -
    diff --git a/openslides/core/static/css/projector.css b/openslides/core/static/css/projector.css index facea0fc5..205efb448 100644 --- a/openslides/core/static/css/projector.css +++ b/openslides/core/static/css/projector.css @@ -273,7 +273,7 @@ li { font-size: 120%; line-height: 40px; } -.result .bold { +.result .bold, .electionresults .bold { font-weight: bold; } .electionresults table { diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index 5ae46342e..c318e485b 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -1030,9 +1030,9 @@ angular.module('OpenSlidesApp.core', [ allowedContent: 'h1 h2 h3 b i u strike sup sub strong em;' + 'blockquote p pre table' + - '(text-align-left,text-align-center,text-align-right,text-align-justify,os-split-before,os-split-after){text-align};' + + '(text-align-left,text-align-center,text-align-right,text-align-justify,os-split-before,os-split-after){text-align, float, padding};' + 'a[!href];' + - 'img[!src,alt]{width,height,float};' + + 'img[!src,alt]{width,height,float, padding};' + 'tr th td caption;' + 'li(os-split-before,os-split-after); ol(os-split-before,os-split-after)[start]{list-style-type};' + 'ul(os-split-before,os-split-after){list-style};' + diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js index bb513a6c6..23f07e568 100644 --- a/openslides/motions/static/js/motions/base.js +++ b/openslides/motions/static/js/motions/base.js @@ -155,7 +155,7 @@ angular.module('OpenSlidesApp.motions', [ // Calculate percent value var base = this.getPercentBase(config, type); if (base) { - percentNumber = Math.round(vote * 100 / (base) * 10) / 10; + percentNumber = Math.round(vote * 100 / (base) * 100) / 100; percentStr = '(' + percentNumber + ' %)'; } return { diff --git a/openslides/utils/validate.py b/openslides/utils/validate.py index bba985dff..973b42bb5 100644 --- a/openslides/utils/validate.py +++ b/openslides/utils/validate.py @@ -16,7 +16,7 @@ allowed_attributes = { 'ol': ['start'], } allowed_styles = [ - 'color', 'background-color', 'height', 'width', 'text-align' + 'color', 'background-color', 'height', 'width', 'text-align', 'float', 'padding' ]