New config to set reason field required.
This commit is contained in:
parent
13b6acf72e
commit
617eccb85f
@ -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
|
||||||
|
@ -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');
|
||||||
|
@ -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> <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 -->
|
||||||
|
@ -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: [],
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user