diff --git a/client/src/app/core/repositories/motions/motion-repository.service.ts b/client/src/app/core/repositories/motions/motion-repository.service.ts
index 32842a1b8..2cad3fbf4 100644
--- a/client/src/app/core/repositories/motions/motion-repository.service.ts
+++ b/client/src/app/core/repositories/motions/motion-repository.service.ts
@@ -715,17 +715,50 @@ export class MotionRepositoryService extends BaseIsAgendaItemAndListOfSpeakersCo
* @param {number} lineLength
*/
public getParagraphsToChoose(motion: ViewMotion, lineLength: number): ParagraphToChoose[] {
- return this.getTextParagraphs(motion, true, lineLength).map((paragraph: string, index: number) => {
- const affected: LineNumberRange = this.lineNumbering.getLineNumberRange(paragraph);
- return {
- paragraphNo: index,
- html: this.lineNumbering.stripLineNumbers(paragraph),
- lineFrom: affected.from,
- lineTo: affected.to
- };
+ const parent = motion.hasParent ? motion.parent : motion;
+ return this.getTextParagraphs(parent, true, lineLength).map((paragraph: string, index: number) => {
+ let localParagraph;
+ if (motion.hasParent) {
+ localParagraph = motion.amendment_paragraphs[index] ? motion.amendment_paragraphs[index] : paragraph;
+ } else {
+ localParagraph = paragraph;
+ }
+ return this.extractAffectedParagraphs(localParagraph, index);
});
}
+ /**
+ * To create paragraph based amendments for amendments, creates diffed paragraphs
+ * for selection
+ */
+ public getDiffedParagraphToChoose(amendment: ViewMotion, lineLength: number): ParagraphToChoose[] {
+ if (amendment.hasParent) {
+ const parent = amendment.parent;
+
+ return this.getTextParagraphs(parent, true, lineLength).map((paragraph: string, index: number) => {
+ const diffedParagraph = amendment.amendment_paragraphs[index]
+ ? this.diff.diff(paragraph, amendment.amendment_paragraphs[index], lineLength)
+ : paragraph;
+ return this.extractAffectedParagraphs(diffedParagraph, index);
+ });
+ } else {
+ throw new Error('getDiffedParagraphToChoose: given amendment has no parent');
+ }
+ }
+
+ /**
+ * Creates a selectable and editable paragraph
+ */
+ private extractAffectedParagraphs(paragraph: string, index: number): ParagraphToChoose {
+ const affected: LineNumberRange = this.lineNumbering.getLineNumberRange(paragraph);
+ return {
+ paragraphNo: index,
+ html: this.lineNumbering.stripLineNumbers(paragraph),
+ lineFrom: affected.from,
+ lineTo: affected.to
+ } as ParagraphToChoose;
+ }
+
/**
* Returns all paragraphs that are affected by the given amendment in diff-format
*
diff --git a/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.html b/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.html
index 976577164..45b136867 100644
--- a/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.html
+++ b/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.html
@@ -34,7 +34,7 @@
{{ 'Select paragraphs' | translate }}
diff --git a/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.ts b/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.ts
index ea418745c..c4e0f26b7 100644
--- a/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.ts
+++ b/client/src/app/site/motions/modules/motion-detail/components/amendment-create-wizard/amendment-create-wizard.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewEncapsulation } from '@angular/core';
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser';
@@ -22,7 +22,7 @@ import { ViewMotion } from 'app/site/motions/models/view-motion';
styleUrls: ['./amendment-create-wizard.component.scss'],
encapsulation: ViewEncapsulation.None
})
-export class AmendmentCreateWizardComponent extends BaseViewComponent {
+export class AmendmentCreateWizardComponent extends BaseViewComponent implements OnInit {
/**
* The motion to be amended
*/
@@ -33,6 +33,17 @@ export class AmendmentCreateWizardComponent extends BaseViewComponent {
*/
public paragraphs: ParagraphToChoose[];
+ /**
+ * Diffed version of the paragraphs, mainly for the preview
+ * in case of amendments of amendments
+ */
+ public diffedParagraphs: ParagraphToChoose[];
+
+ /**
+ * determine if we are in the amendment of amendment mode
+ */
+ private isAmendmentOfAmendment: boolean;
+
/**
* Change recommendation content.
*/
@@ -79,7 +90,9 @@ export class AmendmentCreateWizardComponent extends BaseViewComponent {
) {
super(titleService, translate, matSnackBar);
this.createForm();
+ }
+ public ngOnInit(): void {
this.configService.get('motions_line_length').subscribe(lineLength => {
this.lineLength = lineLength;
this.getMotionByUrl();
@@ -101,12 +114,30 @@ export class AmendmentCreateWizardComponent extends BaseViewComponent {
// load existing motion
this.route.params.subscribe(params => {
this.repo.getViewModelObservable(params.id).subscribe(newViewMotion => {
- this.motion = newViewMotion;
- this.paragraphs = this.repo.getParagraphsToChoose(newViewMotion, this.lineLength);
+ if (newViewMotion) {
+ this.paragraphs = this.repo.getParagraphsToChoose(newViewMotion, this.lineLength);
+
+ if (newViewMotion.hasParent) {
+ this.isAmendmentOfAmendment = true;
+ this.motion = newViewMotion.parent;
+ this.diffedParagraphs = this.repo.getDiffedParagraphToChoose(newViewMotion, this.lineLength);
+ } else {
+ this.isAmendmentOfAmendment = false;
+ this.motion = newViewMotion;
+ }
+ }
});
});
}
+ /**
+ * Creates the selectable preview of the motion paragraphs, depending
+ * on the amendment state
+ */
+ public getParagraphPreview(index: number): string {
+ return this.isAmendmentOfAmendment ? this.diffedParagraphs[index].html : this.paragraphs[index].html;
+ }
+
/**
* Cancel the editing.
* Only fires when the form was dirty
diff --git a/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.ts b/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.ts
index 311807d31..3705d09c4 100644
--- a/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.ts
+++ b/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.ts
@@ -301,6 +301,11 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
*/
public showAmendmentContext = false;
+ /**
+ * Sets the current amendment text mode from the settings
+ */
+ private amendmentTextMode: string;
+
/**
* For using the enum constants from the template
*/
@@ -503,6 +508,9 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.configService
.get('motions_show_sequential_numbers')
.subscribe(shown => (this.showSequential = shown));
+ this.configService
+ .get('motions_amendments_text_mode')
+ .subscribe(amendmentTextMode => (this.amendmentTextMode = amendmentTextMode));
// Update statute paragraphs
this.statuteRepo.getViewModelListObservable().subscribe(newViewStatuteParagraphs => {
@@ -652,24 +660,22 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.amendmentEdit = true;
const parentMotion = this.repo.getViewModel(this.route.snapshot.queryParams.parent);
const defaultTitle = `${this.translate.instant('Amendment to')} ${parentMotion.identifierOrTitle}`;
- const mode = this.configService.instant('motions_amendments_text_mode');
- if (mode === 'freestyle' || mode === 'fulltext') {
- defaultMotion.title = defaultTitle;
- defaultMotion.parent_id = parentMotion.id;
- defaultMotion.category_id = parentMotion.category_id;
- defaultMotion.tags_id = parentMotion.tags_id;
- defaultMotion.motion_block_id = parentMotion.motion_block_id;
- this.contentForm.patchValue({
- title: defaultTitle,
- category_id: parentMotion.category_id,
- motion_block_id: parentMotion.motion_block_id,
- parent_id: parentMotion.id,
- tags_id: parentMotion.tags_id
- });
- }
- if (mode === 'fulltext') {
+ defaultMotion.title = defaultTitle;
+ defaultMotion.parent_id = parentMotion.id;
+ defaultMotion.category_id = parentMotion.category_id;
+ defaultMotion.tags_id = parentMotion.tags_id;
+ defaultMotion.motion_block_id = parentMotion.motion_block_id;
+ this.contentForm.patchValue({
+ title: defaultTitle,
+ category_id: parentMotion.category_id,
+ motion_block_id: parentMotion.motion_block_id,
+ parent_id: parentMotion.id,
+ tags_id: parentMotion.tags_id
+ });
+
+ if (this.amendmentTextMode === 'fulltext') {
defaultMotion.text = parentMotion.text;
- this.contentForm.patchValue({ text: parentMotion.text });
+ this.contentForm.patchValue({ text: defaultMotion.text });
}
}
this.motion = new ViewCreateMotion(new CreateMotion(defaultMotion));
@@ -1082,8 +1088,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* Goes to the amendment creation wizard. Executed via click.
*/
public createAmendment(): void {
- const mode = this.configService.instant('motions_amendments_text_mode');
- if (mode === 'paragraph') {
+ if (this.amendmentTextMode === 'paragraph') {
this.router.navigate(['./create-amendment'], { relativeTo: this.route });
} else {
this.router.navigate(['./motions/new-amendment'], {