diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html index 20c21f1b2..a49a19fbb 100644 --- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html +++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html @@ -76,11 +76,7 @@ Project - @@ -128,7 +124,9 @@ -
+
+ +
@@ -209,8 +207,7 @@

State

+
- - {{ stateLabel }} - + {{ stateLabel }}
@@ -251,8 +243,11 @@  ... -
@@ -260,21 +255,22 @@ {{ recommendationLabel }} -
+
- + - +
- - {{ recommendationLabel }} - + {{ recommendationLabel }}
- + {{ motion.category ? motion.category : '–' }} @@ -312,7 +312,11 @@ {{ block }} - + {{ motion.motion_block ? motion.motion_block : '–' }} @@ -367,6 +371,26 @@ > rate_review + + + @@ -436,26 +460,26 @@
Final version + diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts index 0a7a31f81..16d27ff87 100644 --- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts +++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.ts @@ -38,6 +38,7 @@ import { ViewportService } from '../../../../core/services/viewport.service'; import { ViewUnifiedChange } from '../../models/view-unified-change'; import { ViewStatuteParagraph } from '../../models/view-statute-paragraph'; import { Workflow } from 'app/shared/models/motions/workflow'; +import { LinenumberingService } from '../../services/linenumbering.service'; /** * Component for the motion detail view @@ -336,7 +337,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { private sanitizer: DomSanitizer, private promptService: PromptService, private pdfExport: MotionPdfExportService, - private personalNoteService: PersonalNoteService + private personalNoteService: PersonalNoteService, + private linenumberingService: LinenumberingService ) { super(title, translate, matSnackBar); @@ -599,10 +601,14 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { /** * Save a motion. Calls the "patchValues" function in the MotionObject */ - public async updateMotion(): Promise { + private updateMotionFromForm(): void { const newMotionValues = { ...this.contentForm.value }; - const motion = this.prepareMotionForSave(newMotionValues, Motion); - this.repo.update(motion, this.motionCopy).then(() => (this.editMotion = false), this.raiseError); + this.updateMotion(newMotionValues, this.motionCopy).then(() => (this.editMotion = false), this.raiseError); + } + + private async updateMotion(newMotionValues: Partial, motion: ViewMotion): Promise { + const updateMotion = this.prepareMotionForSave(newMotionValues, Motion); + await this.repo.update(updateMotion, motion); } /** @@ -612,7 +618,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { if (this.newMotion) { this.createMotion(); } else { - this.updateMotion(); + this.updateMotionFromForm(); } } @@ -719,24 +725,20 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { /** * Sets the motions change reco mode - * @param mode Needs to fot to the enum defined in ViewMotion + * @param mode The mode */ public setChangeRecoMode(mode: ChangeRecoMode): void { this.crMode = mode; } /** - * Returns true if the original version (including change recommendation annotation) is to be shown + * Returns true if the given version is to be shown + * + * @param mode The mode to check + * @returns true, if the mode is shown */ - public isRecoModeOriginal(): boolean { - return this.crMode === ChangeRecoMode.Original || this.allChangingObjects.length === 0; - } - - /** - * Returns true if the diff version is to be shown - */ - public isRecoModeDiff(): boolean { - return this.crMode === ChangeRecoMode.Diff && this.allChangingObjects.length > 0; + public isRecoMode(mode: ChangeRecoMode): boolean { + return this.crMode === mode; } /** @@ -779,6 +781,51 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit { this.router.navigate(['./create-amendment'], { relativeTo: this.route }); } + /** + * Sets the modified final version to the final version. + */ + public async createModifiedFinalVersion(): Promise { + // Get the final version and remove line numbers + const changes: ViewUnifiedChange[] = Object.assign([], this.allChangingObjects); + let finalVersion = this.repo.formatMotion( + this.motion.id, + ChangeRecoMode.Final, + changes, + this.lineLength, + this.highlightedLine + ); + finalVersion = this.linenumberingService.stripLineNumbers(finalVersion); + + // Update the motion + try { + // Just confirm this, if there is one modified final version the user would override. + if (this.motion.modified_final_version) { + const content = this.translate.instant('Are you sure to copy the final version to the print template?'); + if (await this.promptService.open(this.motion.title, content)) { + await this.updateMotion({ modified_final_version: finalVersion }, this.motion); + } + } else { + await this.updateMotion({ modified_final_version: finalVersion }, this.motion); + } + } catch (e) { + this.raiseError(e); + } + this.setChangeRecoMode(ChangeRecoMode.ModifiedFinal); + } + + /** + * Deletes the modified final version + */ + public async deleteModifiedFinalVersion(): Promise { + const content = this.translate.instant('Are you sure to delete the print template?'); + if (await this.promptService.open(this.motion.title, content)) { + this.updateMotion({ modified_final_version: '' }, this.motion).then( + () => this.setChangeRecoMode(ChangeRecoMode.Final), + this.raiseError + ); + } + } + /** * Comes from the head bar * diff --git a/client/src/app/site/motions/models/view-motion.ts b/client/src/app/site/motions/models/view-motion.ts index 33582ee08..61a93918a 100644 --- a/client/src/app/site/motions/models/view-motion.ts +++ b/client/src/app/site/motions/models/view-motion.ts @@ -30,7 +30,8 @@ export enum ChangeRecoMode { Original = 'original', Changed = 'changed', Diff = 'diff', - Final = 'agreed' + Final = 'agreed', + ModifiedFinal = 'modified_final_version' } /** @@ -89,6 +90,16 @@ export class ViewMotion extends BaseProjectableModel { return this.motion ? this.motion.reason : null; } + public get modified_final_version(): string { + return this.motion ? this.motion.modified_final_version : null; + } + + public set modified_final_version(value: string) { + if (this.motion) { + this.motion.modified_final_version = value; + } + } + public get weight(): number { return this.motion ? this.motion.weight : null; } diff --git a/client/src/app/site/motions/services/motion-repository.service.ts b/client/src/app/site/motions/services/motion-repository.service.ts index 718fef2ee..bf004f439 100644 --- a/client/src/app/site/motions/services/motion-repository.service.ts +++ b/client/src/app/site/motions/services/motion-repository.service.ts @@ -343,6 +343,19 @@ export class MotionRepositoryService extends BaseRepository case ChangeRecoMode.Final: const appliedChanges: ViewUnifiedChange[] = changes.filter(change => change.isAccepted()); return this.diff.getTextWithChanges(targetMotion, appliedChanges, lineLength, highlightLine); + case ChangeRecoMode.ModifiedFinal: + if (targetMotion.modified_final_version) { + return this.lineNumbering.insertLineNumbers( + targetMotion.modified_final_version, + lineLength, + highlightLine, + null, + 1 + ); + } else { + // Use the final version as fallback, if the modified does not exist. + return this.formatMotion(id, ChangeRecoMode.Final, changes, lineLength, highlightLine); + } default: console.error('unrecognized ChangeRecoMode option (' + crMode + ')'); return null;