From faf8004280fefab553d8065f9970ab5c220f894b Mon Sep 17 00:00:00 2001 From: Sean Engelhardt Date: Thu, 23 Jan 2020 12:46:18 +0100 Subject: [PATCH] Use amendmend wizzard for amendments Allows paragraph based amendments for other paragraph based amendments. Amendments to amendments will be amended to the main motion, but will contain all the changes to the amendments they were refering to solves #5171 --- .../motions/motion-repository.service.ts | 49 ++++++++++++++++--- .../amendment-create-wizard.component.html | 4 +- .../amendment-create-wizard.component.ts | 39 +++++++++++++-- .../motion-detail/motion-detail.component.ts | 43 +++++++++------- 4 files changed, 102 insertions(+), 33 deletions(-) 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'], {