New config to set reason field required.

This commit is contained in:
Emanuel Schütze 2019-01-31 22:33:44 +01:00
parent 13b6acf72e
commit 617eccb85f
6 changed files with 44 additions and 5 deletions

View File

@ -37,6 +37,7 @@ Motions:
- Added multi select action to manage submitters, tags, states and - Added multi select action to manage submitters, tags, states and
recommendations [#4037, #4132]. recommendations [#4037, #4132].
- Added timestampes for motions [#4134]. - Added timestampes for motions [#4134].
- New config option to set reason as required field [#4232]
User: User:
- Added new admin group which grants all permissions. Users of existing group - Added new admin group which grants all permissions. Users of existing group

View File

@ -110,6 +110,7 @@ _('Default line numbering');
_('disabled'); _('disabled');
_('Line length'); _('Line length');
_('The maximum number of characters per line. Relevant when line numbering is enabled. Min: 40'); _('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 reason on projector');
_('Hide meta information box on projector'); _('Hide meta information box on projector');
_('Hide recommendation on projector'); _('Hide recommendation on projector');

View File

@ -493,7 +493,11 @@
></div> ></div>
<!-- The HTML Editor --> <!-- The HTML Editor -->
<editor formControlName="text" [init]="tinyMceSettings" *ngIf="motion && editMotion"></editor> <editor formControlName="text" [init]="tinyMceSettings" *ngIf="motion && editMotion" required></editor>
<div *ngIf="contentForm.get('text').invalid && (contentForm.get('text').dirty || contentForm.get('text').touched)"
class="red-warning-text" translate>
This field is required.
</div>
<!-- Paragraph-based amendments --> <!-- Paragraph-based amendments -->
<ng-container *ngIf="!editMotion && motion.isParagraphBasedAmendment()"> <ng-container *ngIf="!editMotion && motion.isParagraphBasedAmendment()">
@ -502,11 +506,17 @@
<!-- Reason --> <!-- Reason -->
<div *ngIf="motion.reason || editMotion"> <div *ngIf="motion.reason || editMotion">
<h3 translate>Reason</h3> <h3 [ngClass]="(reasonRequired && contentForm.get('reason').invalid && (contentForm.get('reason').dirty || contentForm.get('reason').touched)) ? 'red-warning-text' : ''">
<span translate>Reason</span>&nbsp;<span *ngIf="reasonRequired && editMotion">*</span>
</h3>
<div class="motion-text" *ngIf="!editMotion"><div [innerHtml]="motion.reason"></div></div> <div class="motion-text" *ngIf="!editMotion"><div [innerHtml]="motion.reason"></div></div>
<!-- The HTML Editor --> <!-- The HTML Editor -->
<editor formControlName="reason" [init]="tinyMceSettings" *ngIf="editMotion"></editor> <editor formControlName="reason" [init]="tinyMceSettings" *ngIf="editMotion" required></editor>
<div *ngIf="reasonRequired && contentForm.get('reason').invalid && (contentForm.get('reason').dirty || contentForm.get('reason').touched)"
class="red-warning-text" translate>
This field is required.
</div>
</div> </div>
<!-- Category form --> <!-- Category form -->

View File

@ -124,6 +124,11 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
*/ */
public statutesEnabled: boolean; public statutesEnabled: boolean;
/**
* Value of the config variable `motions_reason_required`
*/
public reasonRequired: boolean;
/** /**
* Value of the config variable `motions_min_supporters` * Value of the config variable `motions_min_supporters`
*/ */
@ -371,6 +376,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
// load config variables // load config variables
this.configService.get('motions_statutes_enabled').subscribe(enabled => (this.statutesEnabled = enabled)); 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_min_supporters').subscribe(supporters => (this.minSupporters = supporters));
this.configService.get('motions_preamble').subscribe(preamble => (this.preamble = preamble)); this.configService.get('motions_preamble').subscribe(preamble => (this.preamble = preamble));
this.configService.get('motions_amendments_enabled').subscribe(enabled => (this.amendmentsEnabled = enabled)); 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 * TODO: Build a custom form validator
*/ */
public createForm(): void { public createForm(): void {
const reason: any[] = [''];
if (this.reasonRequired) {
reason.push(Validators.required);
}
this.contentForm = this.formBuilder.group({ this.contentForm = this.formBuilder.group({
identifier: [''], identifier: [''],
title: ['', Validators.required], title: ['', Validators.required],
text: ['', Validators.required], text: ['', Validators.required],
reason: [''], reason: reason,
category_id: [''], category_id: [''],
attachments_id: [[]], attachments_id: [[]],
agenda_parent_id: [], agenda_parent_id: [],

View File

@ -100,6 +100,16 @@ def get_config_variables():
validators=(MinValueValidator(40),), 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( yield ConfigVariable(
name="motions_disable_reason_on_projector", name="motions_disable_reason_on_projector",
default_value=False, default_value=False,

View File

@ -2,6 +2,7 @@ from typing import Dict, Optional
from django.db import transaction from django.db import transaction
from ..core.config import config
from ..poll.serializers import default_votes_validator from ..poll.serializers import default_votes_validator
from ..utils.auth import get_group_model from ..utils.auth import get_group_model
from ..utils.autoupdate import inform_changed_data from ..utils.autoupdate import inform_changed_data
@ -470,7 +471,13 @@ class MotionSerializer(ModelSerializer):
data["text"] = "" data["text"] = ""
else: else:
if "text" in data and not data["text"]: 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 return data