diff --git a/README.rst b/README.rst
index 21aeb246d..ed09e1219 100644
--- a/README.rst
+++ b/README.rst
@@ -171,8 +171,6 @@ OpenSlides uses the following projects or parts of them:
* `django-jsonfield `_,
License: MIT
-* `jsonschema `_, License: MIT
-
* `natsort `_, License: MIT
* `PyPDF2 `_, License: BSD
@@ -218,7 +216,6 @@ OpenSlides uses the following projects or parts of them:
* `js-data `_, License: MIT
* `js-data-angular `_, License: MIT
* `js-data-http `_, License: MIT
- * `jsen `_, License: MIT
* `lodash `_, License: MIT
* `ng-dialog `_, License: MIT
* `ng-file-upload `_, License: MIT
diff --git a/bower.json b/bower.json
index 2fd28f98c..50b34df4f 100644
--- a/bower.json
+++ b/bower.json
@@ -27,7 +27,6 @@
"jquery.cookie": "~1.4.1",
"js-data": "~2.9.0",
"js-data-angular": "~3.2.1",
- "jsen": "~0.6.1",
"lodash": "~4.16.0",
"ng-dialog": "~0.6.4",
"ng-file-upload": "~11.2.3",
diff --git a/openslides/core/config.py b/openslides/core/config.py
index fddf3b709..41df1035f 100644
--- a/openslides/core/config.py
+++ b/openslides/core/config.py
@@ -12,6 +12,7 @@ INPUT_TYPE_MAPPING = {
'boolean': bool,
'choice': str,
'colorpicker': str,
+ 'comments': list,
'resolution': dict}
@@ -98,6 +99,19 @@ class ConfigHandler:
value['height'] < 600 or value['height'] > 2160):
raise ConfigError(_('The Resolution have to be between 800x600 and 3840x2160.'))
+ if config_variable.input_type == 'comments':
+ if not isinstance(value, list):
+ raise ConfigError(_('motions_comments has to be a list.'))
+ for comment in value:
+ if not isinstance(comment, dict):
+ raise ConfigError(_('Each element in motions_comments has to be a dict.'))
+ if comment.get('name') is None or comment.get('public') is None:
+ raise ConfigError(_('A name and a public property have to be given.'))
+ if not isinstance(comment['name'], str):
+ raise ConfigError(_('name has to be string.'))
+ if not isinstance(comment['public'], bool):
+ raise ConfigError(_('public property has to be bool.'))
+
# Save the new value to the database.
ConfigStore.objects.update_or_create(key=key, defaults={'value': value})
diff --git a/openslides/core/static/css/app.css b/openslides/core/static/css/app.css
index 7d7d2cf08..54c0e4451 100644
--- a/openslides/core/static/css/app.css
+++ b/openslides/core/static/css/app.css
@@ -777,6 +777,11 @@ img {
background-color: transparent;
}
+/** Config **/
+.input-comments > div {
+ margin-bottom: 5px
+}
+
/** Footer **/
#footer {
float: left;
diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js
index ab615b680..ba28ab9ac 100644
--- a/openslides/core/static/js/core/site.js
+++ b/openslides/core/static/js/core/site.js
@@ -862,6 +862,7 @@ angular.module('OpenSlidesApp.core.site', [
boolean: 'checkbox',
choice: 'choice',
colorpicker: 'colorpicker',
+ comments: 'comments',
resolution: 'resolution',
}[type];
}
@@ -1016,7 +1017,8 @@ angular.module('OpenSlidesApp.core.site', [
'$scope',
'Config',
'configOptions',
- function($scope, Config, configOptions) {
+ 'gettextCatalog',
+ function($scope, Config, configOptions, gettextCatalog) {
Config.bindAll({}, $scope, 'configs');
$scope.configGroups = configOptions.data.config_groups;
@@ -1025,6 +1027,19 @@ angular.module('OpenSlidesApp.core.site', [
Config.get(key).value = value;
Config.save(key);
};
+
+ /* For comments input */
+ $scope.addComment = function (key, parent) {
+ parent.value.push({
+ name: gettextCatalog.getString('New'),
+ public: false,
+ });
+ $scope.save(key, parent.value);
+ };
+ $scope.removeComment = function (key, parent, index) {
+ parent.value.splice(index, 1);
+ $scope.save(key, parent.value);
+ };
}
])
diff --git a/openslides/core/static/templates/config-form-field.html b/openslides/core/static/templates/config-form-field.html
index 63f237629..923dd3ab3 100644
--- a/openslides/core/static/templates/config-form-field.html
+++ b/openslides/core/static/templates/config-form-field.html
@@ -31,6 +31,37 @@
type="number">
+
+
+
=0.15,<1.0
djangorestframework>=3.4,<3.5
html5lib>=0.99,<1.0
jsonfield>=0.9.19,<1.1
-jsonschema>=2.5,<2.6
natsort>=3.2,<5.1
PyPDF2>=1.25.0,<1.27
reportlab>=3.0,<3.4
diff --git a/tests/integration/motions/test_viewset.py b/tests/integration/motions/test_viewset.py
index 46d459d9b..2c3b72ab9 100644
--- a/tests/integration/motions/test_viewset.py
+++ b/tests/integration/motions/test_viewset.py
@@ -16,6 +16,7 @@ class CreateMotion(TestCase):
Tests motion creation.
"""
def setUp(self):
+ self.client = APIClient()
self.client.login(username='admin', password='admin')
def test_simple(self):
@@ -106,6 +107,21 @@ class CreateMotion(TestCase):
motion = Motion.objects.get()
self.assertEqual(motion.tags.get().name, 'test_tag_iRee3kiecoos4rorohth')
+ def test_with_multiple_comments(self):
+ config['motions_comments'] = [
+ {'name': 'comment1', 'public': True},
+ {'name': 'comment2', 'public': False}]
+ comments = ['comemnt1_sdpoiuffo3%7dwDwW&', 'comment2_iusd&D/TdskDWH&5DWas46WAd078']
+ response = self.client.post(
+ reverse('motion-list'),
+ {'title': 'title_test_sfdAaufd56HR7sd5FDq7av',
+ 'text': 'text_test_fiuhefF86()ew1Ef346AF6W',
+ 'comments': comments},
+ format='json')
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ motion = Motion.objects.get()
+ self.assertEqual(motion.comments, comments)
+
def test_with_workflow(self):
"""
Test to create a motion with a specific workflow.