Do not require the motion text for paragraph based amendments
This commit is contained in:
parent
0f03eb1446
commit
11fd8c5762
@ -46,32 +46,18 @@
|
|||||||
<mat-step>
|
<mat-step>
|
||||||
<ng-template matStepLabel>{{ 'Change paragraph' | translate }}</ng-template>
|
<ng-template matStepLabel>{{ 'Change paragraph' | translate }}</ng-template>
|
||||||
|
|
||||||
<h3><span translate>Amendment text</span> <span>*</span></h3>
|
<h3><span translate>Amendment text</span></h3>
|
||||||
|
|
||||||
<!-- Text -->
|
<!-- Text -->
|
||||||
<section *ngFor="let paragraph of contentForm.value.selectedParagraphs">
|
<section *ngFor="let paragraph of contentForm.value.selectedParagraphs">
|
||||||
<h4 [class.red-warning-text]="contentForm.get('text_' + paragraph.paragraphNo).invalid && (
|
<h4>
|
||||||
contentForm.get('text_' + paragraph.paragraphNo).dirty ||
|
|
||||||
contentForm.get('text_' + paragraph.paragraphNo).touched
|
|
||||||
)"
|
|
||||||
>
|
|
||||||
<span *ngIf="paragraph.lineFrom >= paragraph.lineTo - 1" class="line-number">
|
<span *ngIf="paragraph.lineFrom >= paragraph.lineTo - 1" class="line-number">
|
||||||
{{ 'Line' | translate }} {{ paragraph.lineFrom }}</span> <span>*</span>
|
{{ 'Line' | translate }} {{ paragraph.lineFrom }}:</span>
|
||||||
<span *ngIf="paragraph.lineFrom < paragraph.lineTo - 1" class="line-number">
|
<span *ngIf="paragraph.lineFrom < paragraph.lineTo - 1" class="line-number">
|
||||||
{{ 'Line' | translate }} {{ paragraph.lineFrom }}
|
{{ 'Line' | translate }} {{ paragraph.lineFrom }}
|
||||||
- {{ paragraph.lineTo - 1 }}</span> <span>*</span>
|
- {{ paragraph.lineTo - 1 }}:</span>
|
||||||
</h4>
|
</h4>
|
||||||
<editor [formControlName]="'text_' + paragraph.paragraphNo" [init]="tinyMceSettings" required></editor>
|
<editor [formControlName]="'text_' + paragraph.paragraphNo" [init]="tinyMceSettings"></editor>
|
||||||
<div
|
|
||||||
*ngIf="contentForm.get('text_' + paragraph.paragraphNo).invalid && (
|
|
||||||
contentForm.get('text_' + paragraph.paragraphNo).dirty ||
|
|
||||||
contentForm.get('text_' + paragraph.paragraphNo).touched
|
|
||||||
)"
|
|
||||||
class="red-warning-text"
|
|
||||||
translate
|
|
||||||
>
|
|
||||||
This field is required.
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Reason -->
|
<!-- Reason -->
|
||||||
|
@ -645,15 +645,14 @@
|
|||||||
<!-- The HTML Editor for paragraph-based amendments -->
|
<!-- The HTML Editor for paragraph-based amendments -->
|
||||||
<ng-container *ngIf="motion && editMotion && motion.isParagraphBasedAmendment()">
|
<ng-container *ngIf="motion && editMotion && motion.isParagraphBasedAmendment()">
|
||||||
<section *ngFor="let paragraph of contentForm.value.selected_paragraphs">
|
<section *ngFor="let paragraph of contentForm.value.selected_paragraphs">
|
||||||
<h4>
|
<h3>
|
||||||
<span *ngIf="paragraph.lineFrom >= paragraph.lineTo - 1" class="line-number">
|
<span *ngIf="paragraph.lineFrom >= paragraph.lineTo - 1" class="line-number">
|
||||||
{{ 'Line' | translate }} {{ paragraph.lineFrom }}</span
|
{{ 'Line' | translate }} {{ paragraph.lineFrom }}
|
||||||
>
|
</span>
|
||||||
<span *ngIf="paragraph.lineFrom < paragraph.lineTo - 1" class="line-number">
|
<span *ngIf="paragraph.lineFrom < paragraph.lineTo - 1" class="line-number">
|
||||||
{{ 'Line' | translate }} {{ paragraph.lineFrom }} - {{ paragraph.lineTo - 1 }}</span
|
{{ 'Line' | translate }} {{ paragraph.lineFrom }} - {{ paragraph.lineTo - 1 }}
|
||||||
>
|
</span>
|
||||||
<span>*</span>
|
</h3>
|
||||||
</h4>
|
|
||||||
<editor [formControlName]="'text_' + paragraph.paragraphNo" [init]="tinyMceSettings" required></editor>
|
<editor [formControlName]="'text_' + paragraph.paragraphNo" [init]="tinyMceSettings" required></editor>
|
||||||
<div
|
<div
|
||||||
*ngIf="
|
*ngIf="
|
||||||
@ -840,13 +839,13 @@
|
|||||||
*ngIf="paragraph.diffLineTo === paragraph.diffLineFrom + 1 && !showAmendmentContext"
|
*ngIf="paragraph.diffLineTo === paragraph.diffLineFrom + 1 && !showAmendmentContext"
|
||||||
class="amendment-line-header"
|
class="amendment-line-header"
|
||||||
>
|
>
|
||||||
<span translate>Line</span> {{ paragraph.diffLineFrom }}:
|
{{ 'Line' | translate }} {{ paragraph.diffLineFrom }}:
|
||||||
</h3>
|
</h3>
|
||||||
<h3
|
<h3
|
||||||
*ngIf="paragraph.diffLineTo !== paragraph.diffLineFrom + 1 && !showAmendmentContext"
|
*ngIf="paragraph.diffLineTo !== paragraph.diffLineFrom + 1 && !showAmendmentContext"
|
||||||
class="amendment-line-header"
|
class="amendment-line-header"
|
||||||
>
|
>
|
||||||
<span translate>Line</span> {{ paragraph.diffLineFrom }} - {{ paragraph.diffLineTo - 1 }}:
|
{{ 'Line' | translate }} {{ paragraph.diffLineFrom }} - {{ paragraph.diffLineTo - 1 }}:
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="paragraphcontext" [innerHtml]="sanitizedText(paragraph.textPre)"></div>
|
<div class="paragraphcontext" [innerHtml]="sanitizedText(paragraph.textPre)"></div>
|
||||||
|
@ -77,6 +77,10 @@ span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.amendment-line-header {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
.motion-content {
|
.motion-content {
|
||||||
h4 {
|
h4 {
|
||||||
margin: 10px 10px 15px 0;
|
margin: 10px 10px 15px 0;
|
||||||
|
@ -656,7 +656,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
|
|
||||||
paragraphsToChoose.forEach(
|
paragraphsToChoose.forEach(
|
||||||
(paragraph: ParagraphToChoose, paragraphNo: number): void => {
|
(paragraph: ParagraphToChoose, paragraphNo: number): void => {
|
||||||
if (formMotion.amendment_paragraphs[paragraphNo]) {
|
if (formMotion.amendment_paragraphs[paragraphNo] !== null) {
|
||||||
this.contentForm.addControl(
|
this.contentForm.addControl(
|
||||||
'text_' + paragraphNo,
|
'text_' + paragraphNo,
|
||||||
new FormControl('', Validators.required)
|
new FormControl('', Validators.required)
|
||||||
|
@ -401,7 +401,8 @@ class MotionSerializer(ModelSerializer):
|
|||||||
modified_final_version = CharField(allow_blank=True, required=False)
|
modified_final_version = CharField(allow_blank=True, required=False)
|
||||||
reason = CharField(allow_blank=True, required=False)
|
reason = CharField(allow_blank=True, required=False)
|
||||||
state_restriction = SerializerMethodField()
|
state_restriction = SerializerMethodField()
|
||||||
text = CharField(allow_blank=True)
|
text = CharField(allow_blank=True, required=False) # This will be checked
|
||||||
|
# during validation
|
||||||
title = CharField(max_length=255)
|
title = CharField(max_length=255)
|
||||||
amendment_paragraphs = AmendmentParagraphsJSONSerializerField(required=False)
|
amendment_paragraphs = AmendmentParagraphsJSONSerializerField(required=False)
|
||||||
workflow_id = IntegerField(
|
workflow_id = IntegerField(
|
||||||
@ -472,6 +473,7 @@ class MotionSerializer(ModelSerializer):
|
|||||||
if "reason" in data:
|
if "reason" in data:
|
||||||
data["reason"] = validate_html(data["reason"])
|
data["reason"] = validate_html(data["reason"])
|
||||||
|
|
||||||
|
# The motion text is only needed, if it is not a paragraph based amendment.
|
||||||
if "amendment_paragraphs" in data:
|
if "amendment_paragraphs" in data:
|
||||||
data["amendment_paragraphs"] = list(
|
data["amendment_paragraphs"] = list(
|
||||||
map(
|
map(
|
||||||
@ -483,7 +485,9 @@ class MotionSerializer(ModelSerializer):
|
|||||||
)
|
)
|
||||||
data["text"] = ""
|
data["text"] = ""
|
||||||
else:
|
else:
|
||||||
if "text" in data and not data["text"]:
|
if (self.partial and "text" in data and not data["text"]) or (
|
||||||
|
not self.partial and not data.get("text")
|
||||||
|
):
|
||||||
raise ValidationError({"detail": "The text field may not be blank."})
|
raise ValidationError({"detail": "The text field may not be blank."})
|
||||||
if config["motions_reason_required"]:
|
if config["motions_reason_required"]:
|
||||||
if (self.partial and "reason" in data and not data["reason"]) or (
|
if (self.partial and "reason" in data and not data["reason"]) or (
|
||||||
|
@ -266,9 +266,15 @@ class CreateMotion(TestCase):
|
|||||||
def test_without_data(self):
|
def test_without_data(self):
|
||||||
response = self.client.post(reverse("motion-list"), {})
|
response = self.client.post(reverse("motion-list"), {})
|
||||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
self.assertTrue("title" in response.data)
|
||||||
|
|
||||||
|
def test_without_text(self):
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("motion-list"), {"title": "test_title_dlofp23m9O(ZD2d1lwHG"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.data,
|
str(response.data["detail"][0]), "The text field may not be blank."
|
||||||
{"title": ["This field is required."], "text": ["This field is required."]},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_with_category(self):
|
def test_with_category(self):
|
||||||
@ -569,6 +575,14 @@ class UpdateMotion(TestCase):
|
|||||||
self.assertEqual(motion.title, "test_title_aeng7ahChie3waiR8xoh")
|
self.assertEqual(motion.title, "test_title_aeng7ahChie3waiR8xoh")
|
||||||
self.assertEqual(motion.identifier, "test_identifier_jieseghohj7OoSah1Ko9")
|
self.assertEqual(motion.identifier, "test_identifier_jieseghohj7OoSah1Ko9")
|
||||||
|
|
||||||
|
def test_patch_empty_text(self):
|
||||||
|
response = self.client.patch(
|
||||||
|
reverse("motion-detail", args=[self.motion.pk]), {"text": ""}, format="json"
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
|
motion = Motion.objects.get()
|
||||||
|
self.assertEqual(motion.text, "test_text_xeigheeha7thopubeu4U")
|
||||||
|
|
||||||
def test_patch_workflow(self):
|
def test_patch_workflow(self):
|
||||||
"""
|
"""
|
||||||
Tests to only update the workflow of a motion.
|
Tests to only update the workflow of a motion.
|
||||||
|
Loading…
Reference in New Issue
Block a user