diff --git a/openslides/motions/migrations/0007_auto_20161027_1406.py b/openslides/motions/migrations/0007_auto_20161027_1406.py new file mode 100644 index 000000000..90e3abc03 --- /dev/null +++ b/openslides/motions/migrations/0007_auto_20161027_1406.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.2 on 2016-10-27 12:06 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('motions', '0006_auto_20161017_2020'), + ] + + operations = [ + migrations.AddField( + model_name='state', + name='show_recommendation_extension_field', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='state', + name='show_state_extension_field', + field=models.BooleanField(default=False), + ), + ] diff --git a/openslides/motions/models.py b/openslides/motions/models.py index fdde434ef..f523aa5ab 100644 --- a/openslides/motions/models.py +++ b/openslides/motions/models.py @@ -1085,6 +1085,20 @@ class State(RESTModelMixin, models.Model): this one, else it does. """ + show_state_extension_field = models.BooleanField(default=False) + """ + If true, an additional input field (from motion comment) is visible + to extend the state name. The full state name is composed of the given + state name and the entered value of this input field. + """ + + show_recommendation_extension_field = models.BooleanField(default=False) + """ + If true, an additional input field (from motion comment) is visible + to extend the recommendation label. The full recommendation string is + composed of the given recommendation label and the entered value of this input field. + """ + class Meta: default_permissions = () diff --git a/openslides/motions/serializers.py b/openslides/motions/serializers.py index 8a8373fce..9f19e53f0 100644 --- a/openslides/motions/serializers.py +++ b/openslides/motions/serializers.py @@ -71,6 +71,8 @@ class StateSerializer(ModelSerializer): 'versioning', 'leave_old_version_active', 'dont_set_identifier', + 'show_state_extension_field', + 'show_recommendation_extension_field', 'next_states', 'workflow') diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js index 3246e0256..fbb818cf7 100644 --- a/openslides/motions/static/js/motions/base.js +++ b/openslides/motions/static/js/motions/base.js @@ -147,11 +147,12 @@ angular.module('OpenSlidesApp.motions', [ 'MotionComment', 'jsDataModel', 'gettext', + 'gettextCatalog', 'operator', 'Config', 'lineNumberingService', 'diffService', - function(DS, MotionPoll, MotionChangeRecommendation, MotionComment, jsDataModel, gettext, operator, Config, + function(DS, MotionPoll, MotionChangeRecommendation, MotionComment, jsDataModel, gettext, gettextCatalog, operator, Config, lineNumberingService, diffService) { var name = 'motions/motion'; return DS.defineResource({ @@ -288,6 +289,38 @@ angular.module('OpenSlidesApp.motions', [ getReason: function (versionId) { return this.getVersion(versionId).reason; }, + // full state name - optional with custom state name extension + // depended by state and provided by a custom comment field + getStateName: function () { + var additionalName = ''; + if (this.state.show_state_extension_field) { + // check motion comment fields for flag 'forState' + var fields = Config.get('motions_comments').value; + var index = _.findIndex(fields, ['forState', true]); + if (index > -1) { + additionalName = ' ' + this.comments[index]; + } + } + return gettextCatalog.getString(this.state.name) + additionalName; + }, + // full recommendation string - optional with custom recommendationextension + // depended by state and provided by a custom comment field + getRecommendationName: function () { + var recommendation = ''; + var additionalName = ''; + if (this.recommendation) { + recommendation = gettextCatalog.getString(this.recommendation.recommendation_label); + if (this.recommendation.show_recommendation_extension_field) { + // check motion comment fields for flag 'forRecommendation' + var fields = Config.get('motions_comments').value; + var index = _.findIndex(fields, ['forRecommendation', true]); + if (index > -1) { + additionalName = ' ' + this.comments[index]; + } + } + } + return recommendation + additionalName; + }, // link name which is shown in search result getSearchResultName: function () { return this.getTitle(); @@ -450,7 +483,7 @@ angular.module('OpenSlidesApp.motions', [ getFormFields: function () { var fields = Config.get('motions_comments').value; return _.map( - fields, + _.filter(fields, function(element) { return !element.forState && !element.forRecommendation; }), function (field) { return { key: 'comment ' + field.name, @@ -484,7 +517,16 @@ angular.module('OpenSlidesApp.motions', [ for (var i = 0; i < fields.length; i++) { motion.comments.push(motion['comment ' + fields[i].name] || ''); } - } + }, + getFieldNameForFlag: function (flag) { + var fields = Config.get('motions_comments').value; + var fieldName = ''; + var index = _.findIndex(fields, [flag, true]); + if (index > -1) { + fieldName = fields[index].name; + } + return fieldName; + }, }; } ]) diff --git a/openslides/motions/static/js/motions/docx.js b/openslides/motions/static/js/motions/docx.js index d9f7d4da7..6b3b7ef97 100644 --- a/openslides/motions/static/js/motions/docx.js +++ b/openslides/motions/static/js/motions/docx.js @@ -82,7 +82,7 @@ angular.module('OpenSlidesApp.motions.DOCX', []) }).join(', '), signature_translation: signature_translation, status_translation: status_translation, - status: gettextCatalog.getString(motion.state.name), + status: motion.getStateName(), text: html2docx(motion.getText()), reason_translation: motion.getReason().length === 0 ? '' : reason_translation, reason: html2docx(motion.getReason()), diff --git a/openslides/motions/static/js/motions/pdf.js b/openslides/motions/static/js/motions/pdf.js index 6f23a158a..a3a960670 100644 --- a/openslides/motions/static/js/motions/pdf.js +++ b/openslides/motions/static/js/motions/pdf.js @@ -42,7 +42,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf']) // Generate text of signment var signment = function() { var label = converter.createElement("text", gettextCatalog.getString('Submitter') + ':\nStatus:'); - var state = converter.createElement("text", User.get(motion.submitters_id[0]).full_name + '\n'+gettextCatalog.getString(motion.state.name)); + var state = converter.createElement("text", User.get(motion.submitters_id[0]).full_name + '\n' + motion.getStateName()); state.width = "70%"; label.width = "30%"; label.bold = true; diff --git a/openslides/motions/static/js/motions/site.js b/openslides/motions/static/js/motions/site.js index d54514c96..4f0534610 100644 --- a/openslides/motions/static/js/motions/site.js +++ b/openslides/motions/static/js/motions/site.js @@ -1013,6 +1013,7 @@ angular.module('OpenSlidesApp.motions.site', [ 'MotionChangeRecommendation', 'MotionPDFExport', 'Motion', + 'MotionComment', 'Category', 'Mediafile', 'Tag', @@ -1026,9 +1027,8 @@ angular.module('OpenSlidesApp.motions.site', [ 'ProjectionDefault', function($scope, $http, operator, ngDialog, MotionForm, ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation, MotionPDFExport, - Motion, Category, Mediafile, Tag, User, Workflow, Config, motion, MotionInlineEditing, gettextCatalog, + Motion, MotionComment, Category, Mediafile, Tag, User, Workflow, Config, motion, MotionInlineEditing, gettextCatalog, Projector, ProjectionDefault) { - Motion.bindOne(motion.id, $scope, 'motion'); Category.bindAll({}, $scope, 'categories'); Mediafile.bindAll({}, $scope, 'mediafiles'); Tag.bindAll({}, $scope, 'tags'); @@ -1041,10 +1041,17 @@ angular.module('OpenSlidesApp.motions.site', [ }, function () { $scope.defaultProjectorId = ProjectionDefault.filter({name: 'motions'})[0].projector_id; }); + $scope.$watch(function () { + return Motion.lastModified(motion.id); + }, function () { + $scope.motion = Motion.get(motion.id); + MotionComment.populateFields($scope.motion); + }); + $scope.commentsFields = Config.get('motions_comments').value; + $scope.commentFieldForState = MotionComment.getFieldNameForFlag('forState'); + $scope.commentFieldForRecommendation = MotionComment.getFieldNameForFlag('forRecommendation'); $scope.version = motion.active_version; $scope.isCollapsed = true; - $scope.commentsFields = Config.get('motions_comments').value; - $scope.lineNumberMode = Config.get('motions_default_line_numbering').value; $scope.setLineNumberMode = function(mode) { $scope.lineNumberMode = mode; @@ -1119,6 +1126,26 @@ angular.module('OpenSlidesApp.motions.site', [ $scope.reset_state = function () { $http.put('/rest/motions/motion/' + motion.id + '/set_state/', {}); }; + // save additional state field + $scope.saveAdditionalStateField = function (stateExtension) { + if (stateExtension) { + motion["comment " + $scope.commentFieldForState] = stateExtension; + motion.title = motion.getTitle(-1); + motion.text = motion.getText(-1); + motion.reason = motion.getReason(-1); + Motion.save(motion); + } + }; + // save additional recommendation field + $scope.saveAdditionalRecommendationField = function (recommendationExtension) { + if (recommendationExtension) { + motion["comment " + $scope.commentFieldForRecommendation] = recommendationExtension; + motion.title = motion.getTitle(-1); + motion.text = motion.getText(-1); + motion.reason = motion.getReason(-1); + Motion.save(motion); + } + }; // update recommendation $scope.updateRecommendation = function (recommendation_id) { $http.put('/rest/motions/motion/' + motion.id + '/set_recommendation/', {'recommendation': recommendation_id}); @@ -1183,7 +1210,7 @@ angular.module('OpenSlidesApp.motions.site', [ isAllowed = operator.hasPerms('motions.can_see_and_manage_comments') || _.find( $scope.commentsFields, function(field) { - return field.public; + return field.public && !field.forState && !field.forRecommendation; } ); } diff --git a/openslides/motions/static/templates/motions/motion-block-detail.html b/openslides/motions/static/templates/motions/motion-block-detail.html index eb471aabf..e0b1921a9 100644 --- a/openslides/motions/static/templates/motions/motion-block-detail.html +++ b/openslides/motions/static/templates/motions/motion-block-detail.html @@ -65,11 +65,11 @@
- {{ motion.state.name | translate }} + {{ motion.getStateName() }}
-
- {{ motion.recommendation.recommendation_label | translate }} -
+
+ {{ motion.getRecommendationName() }} +
diff --git a/openslides/motions/static/templates/motions/motion-detail.html b/openslides/motions/static/templates/motions/motion-detail.html index 4ba4a5264..e92738d73 100644 --- a/openslides/motions/static/templates/motions/motion-detail.html +++ b/openslides/motions/static/templates/motions/motion-detail.html @@ -115,7 +115,19 @@
- {{ motion.state.name | translate }} + {{ motion.getStateName() }} +
+
+ + + + +
@@ -142,7 +154,19 @@
- {{ motion.recommendation.recommendation_label | translate }} + {{ motion.getRecommendationName() }} +
+
+ + + + +
@@ -405,9 +429,10 @@
-

Motion Comments

+

Comments

-
+

{{ field.name }} internal diff --git a/openslides/motions/static/templates/motions/motion-list.html b/openslides/motions/static/templates/motions/motion-list.html index 0c7196226..f013379c8 100644 --- a/openslides/motions/static/templates/motions/motion-list.html +++ b/openslides/motions/static/templates/motions/motion-list.html @@ -389,7 +389,7 @@ - {{ motion.state.name | translate }} + {{ motion.getStateName() }} diff --git a/openslides/motions/static/templates/motions/slide_motion.html b/openslides/motions/static/templates/motions/slide_motion.html index 7e5a13d29..26c915f71 100644 --- a/openslides/motions/static/templates/motions/slide_motion.html +++ b/openslides/motions/static/templates/motions/slide_motion.html @@ -3,7 +3,7 @@