diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 3d1656262..dbbc78568 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -37,6 +37,7 @@ Motions:
- Added multi select action to manage submitters, tags, states and
recommendations [#4037, #4132].
- Added timestampes for motions [#4134].
+ - New config option to set reason as required field [#4232]
User:
- Added new admin group which grants all permissions. Users of existing group
diff --git a/client/src/app/core/marked-translations.ts b/client/src/app/core/marked-translations.ts
index f7dc5bc3c..937b73124 100644
--- a/client/src/app/core/marked-translations.ts
+++ b/client/src/app/core/marked-translations.ts
@@ -110,6 +110,7 @@ _('Default line numbering');
_('disabled');
_('Line length');
_('The maximum number of characters per line. Relevant when line numbering is enabled. Min: 40');
+_('Reason required for creating new motion');
_('Hide reason on projector');
_('Hide meta information box on projector');
_('Hide recommendation on projector');
diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html
index 8a53a3a81..407e1f231 100644
--- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html
+++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html
@@ -493,7 +493,11 @@
>
-
+
+
+ This field is required.
+
@@ -502,11 +506,17 @@
-
Reason
+
+ Reason *
+
-
+
+
+ This field is required.
+
diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts
index 4320ca0ce..48983b424 100644
--- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts
+++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts
@@ -124,6 +124,11 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
*/
public statutesEnabled: boolean;
+ /**
+ * Value of the config variable `motions_reason_required`
+ */
+ public reasonRequired: boolean;
+
/**
* Value of the config variable `motions_min_supporters`
*/
@@ -371,6 +376,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
// load config variables
this.configService.get('motions_statutes_enabled').subscribe(enabled => (this.statutesEnabled = enabled));
+ this.configService.get('motions_reason_required').subscribe(required => (this.reasonRequired = required));
this.configService.get('motions_min_supporters').subscribe(supporters => (this.minSupporters = supporters));
this.configService.get('motions_preamble').subscribe(preamble => (this.preamble = preamble));
this.configService.get('motions_amendments_enabled').subscribe(enabled => (this.amendmentsEnabled = enabled));
@@ -520,11 +526,15 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
* TODO: Build a custom form validator
*/
public createForm(): void {
+ const reason: any[] = [''];
+ if (this.reasonRequired) {
+ reason.push(Validators.required);
+ }
this.contentForm = this.formBuilder.group({
identifier: [''],
title: ['', Validators.required],
text: ['', Validators.required],
- reason: [''],
+ reason: reason,
category_id: [''],
attachments_id: [[]],
agenda_parent_id: [],
diff --git a/openslides/motions/config_variables.py b/openslides/motions/config_variables.py
index 8abc91a4c..843dfd8e2 100644
--- a/openslides/motions/config_variables.py
+++ b/openslides/motions/config_variables.py
@@ -100,6 +100,16 @@ def get_config_variables():
validators=(MinValueValidator(40),),
)
+ yield ConfigVariable(
+ name="motions_reason_required",
+ default_value=False,
+ input_type="boolean",
+ label="Reason required for creating new motion",
+ weight=324,
+ group="Motions",
+ subgroup="General",
+ )
+
yield ConfigVariable(
name="motions_disable_reason_on_projector",
default_value=False,
diff --git a/openslides/motions/serializers.py b/openslides/motions/serializers.py
index eb273407b..55336f903 100644
--- a/openslides/motions/serializers.py
+++ b/openslides/motions/serializers.py
@@ -2,6 +2,7 @@ from typing import Dict, Optional
from django.db import transaction
+from ..core.config import config
from ..poll.serializers import default_votes_validator
from ..utils.auth import get_group_model
from ..utils.autoupdate import inform_changed_data
@@ -470,7 +471,13 @@ class MotionSerializer(ModelSerializer):
data["text"] = ""
else:
if "text" in data and not data["text"]:
- raise ValidationError({"detail": "This field may not be blank."})
+ raise ValidationError({"detail": "The text field may not be blank."})
+ if (
+ "reason" in data
+ and not data["reason"]
+ and config["motions_reason_required"]
+ ):
+ raise ValidationError({"detail": "The reason field may not be blank."})
return data