modified final version

This commit is contained in:
FinnStutzenstein 2018-12-13 16:26:08 +01:00 committed by Sean Engelhardt
parent a1dc92bf0a
commit d6fcef79c0
4 changed files with 155 additions and 51 deletions

View File

@ -76,11 +76,7 @@
<span translate>Project</span>
</button>
<!-- New amendment -->
<button
mat-menu-item
(click)="createAmendment()"
*ngIf="perms.isAllowed('can_create_amendments', motion)"
>
<button mat-menu-item (click)="createAmendment()" *ngIf="perms.isAllowed('can_create_amendments', motion)">
<mat-icon>add</mat-icon>
<span translate>New amendment</span>
</button>
@ -128,7 +124,9 @@
<mat-divider *ngIf="!editMotion" class="spacer-top-10 spacer-bottom-20"></mat-divider>
<!-- Content -->
<div class="hspacing" [ngClass]="editMotion ? 'os-form-card-mobile' : 'os-card-mobile'"><ng-container *ngTemplateOutlet="contentTemplate"></ng-container></div>
<div class="hspacing" [ngClass]="editMotion ? 'os-form-card-mobile' : 'os-card-mobile'">
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
</div>
<mat-divider *ngIf="!editMotion" class="spacer-top-10 spacer-bottom-20"></mat-divider>
@ -209,8 +207,7 @@
<h4 translate>State</h4>
<mat-menu #stateMenu="matMenu">
<button *ngFor="let state of motion.nextStates" mat-menu-item (click)="setState(state.id)">
{{ state.name | translate }}
<span *ngIf="state.show_state_extension_field">&nbsp;...</span>
{{ state.name | translate }} <span *ngIf="state.show_state_extension_field">&nbsp;...</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item (click)="setState(null)" *ngIf="perms.isAllowed('change_metadata', motion)">
@ -223,18 +220,13 @@
</mat-basic-chip>
<div *ngIf="motion.state.show_state_extension_field" class="spacer-top-10">
<mat-form-field>
<input matInput placeholder="{{ 'Extension' | translate }}"
[(ngModel)]="newStateExtension"/>
<input matInput placeholder="{{ 'Extension' | translate }}" [(ngModel)]="newStateExtension" />
</mat-form-field>
<button mat-icon-button (click)="setStateExtension()">
<mat-icon>check</mat-icon>
</button>
<button mat-icon-button (click)="setStateExtension()"><mat-icon>check</mat-icon></button>
</div>
</div>
<div *ngIf="!perms.isAllowed('change_metadata', motion)">
<mat-basic-chip [ngClass]="getStateCssColor()" >
{{ stateLabel }}
</mat-basic-chip>
<mat-basic-chip [ngClass]="getStateCssColor()"> {{ stateLabel }} </mat-basic-chip>
</div>
</div>
@ -251,8 +243,11 @@
<span *ngIf="recommendation.show_recommendation_extension_field">&nbsp;...</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item *ngIf="perms.isAllowed('change_metadata', motion)"
(click)="setRecommendation(null)">
<button
mat-menu-item
*ngIf="perms.isAllowed('change_metadata', motion)"
(click)="setRecommendation(null)"
>
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
</button>
</mat-menu>
@ -260,21 +255,22 @@
<mat-basic-chip [matMenuTriggerFor]="recommendationMenu" class="bluegrey">
{{ recommendationLabel }}
</mat-basic-chip>
<div *ngIf="motion.recommendation && motion.recommendation.show_recommendation_extension_field"
class="spacer-top-10">
<div
*ngIf="motion.recommendation && motion.recommendation.show_recommendation_extension_field"
class="spacer-top-10"
>
<mat-form-field>
<input matInput placeholder="{{ 'Extension' | translate }}"
[(ngModel)]="newRecommendationExtension"/>
<input
matInput
placeholder="{{ 'Extension' | translate }}"
[(ngModel)]="newRecommendationExtension"
/>
</mat-form-field>
<button mat-icon-button (click)="setRecommendationExtension()">
<mat-icon>check</mat-icon>
</button>
<button mat-icon-button (click)="setRecommendationExtension()"><mat-icon>check</mat-icon></button>
</div>
</div>
<div *ngIf="!perms.isAllowed('change_metadata', motion)">
<mat-basic-chip class="bluegrey">
{{ recommendationLabel }}
</mat-basic-chip>
<mat-basic-chip class="bluegrey"> {{ recommendationLabel }} </mat-basic-chip>
</div>
<button mat-button *ngIf="canFollowRecommendation()" (click)="onFollowRecButton()">
<span translate>Follow recommendation</span>
@ -295,7 +291,11 @@
{{ category }}
</button>
</mat-menu>
<mat-basic-chip *ngIf="perms.isAllowed('change_metadata', motion)" [matMenuTriggerFor]="categoryMenu" class="grey">
<mat-basic-chip
*ngIf="perms.isAllowed('change_metadata', motion)"
[matMenuTriggerFor]="categoryMenu"
class="grey"
>
{{ motion.category ? motion.category : '' }}
</mat-basic-chip>
<mat-basic-chip *ngIf="!perms.isAllowed('change_metadata', motion)" class="grey">
@ -312,7 +312,11 @@
{{ block }}
</button>
</mat-menu>
<mat-basic-chip *ngIf="perms.isAllowed('change_metadata', motion)" [matMenuTriggerFor]="blockMenu" class="grey">
<mat-basic-chip
*ngIf="perms.isAllowed('change_metadata', motion)"
[matMenuTriggerFor]="blockMenu"
class="grey"
>
{{ motion.motion_block ? motion.motion_block : '' }}
</mat-basic-chip>
<mat-basic-chip *ngIf="!perms.isAllowed('change_metadata', motion)" class="grey">
@ -367,6 +371,26 @@
>
<mat-icon>rate_review</mat-icon>
</button>
<button
type="button"
mat-icon-button
matTooltip="{{ 'Create final print template' | translate }}"
*ngIf="isRecoMode(ChangeRecoMode.Final)"
(click)="createModifiedFinalVersion()"
>
<mat-icon>description</mat-icon>
</button>
<button
type="button"
class="red-warning-text"
mat-button
matTooltip="{{ 'Delete final print template' | translate }}"
*ngIf="isRecoMode(ChangeRecoMode.ModifiedFinal)"
(click)="deleteModifiedFinalVersion()"
>
<mat-icon>description</mat-icon>
</button>
</div>
<!-- Selecting statute paragraphs for amendment -->
@ -436,26 +460,26 @@
<!-- Regular motions or traditional amendments -->
<ng-container *ngIf="!editMotion && !motion.isStatuteAmendment() && !motion.isParagraphBasedAmendment()">
<div
*ngIf="!isRecoModeDiff()"
*ngIf="!isRecoMode(ChangeRecoMode.Diff)"
class="motion-text"
[class.line-numbers-none]="isLineNumberingNone()"
[class.line-numbers-inline]="isLineNumberingInline()"
[class.line-numbers-outside]="isLineNumberingOutside()"
>
<os-motion-detail-original-change-recommendations
*ngIf="isLineNumberingOutside() && isRecoModeOriginal()"
*ngIf="isLineNumberingOutside() && isRecoMode(ChangeRecoMode.Original)"
[html]="getFormattedTextPlain()"
[changeRecommendations]="changeRecommendations"
(createChangeRecommendation)="createChangeRecommendation($event)"
(gotoChangeRecommendation)="gotoChangeRecommendation($event)"
></os-motion-detail-original-change-recommendations>
<div
*ngIf="!isLineNumberingOutside() || !isRecoModeOriginal()"
*ngIf="!isLineNumberingOutside() || !isRecoMode(ChangeRecoMode.Original)"
[innerHTML]="sanitizedText(getFormattedTextPlain())"
></div>
</div>
<os-motion-detail-diff
*ngIf="isRecoModeDiff()"
*ngIf="isRecoMode(ChangeRecoMode.Diff)"
[motion]="motion"
[changes]="allChangingObjects"
[scrollToChange]="scrollToChange"
@ -695,4 +719,13 @@
>
Final version
</button>
<button
mat-menu-item
translate
*ngIf="motion?.modified_final_version"
(click)="setChangeRecoMode(ChangeRecoMode.ModifiedFinal)"
[ngClass]="{ selected: motion?.crMode === ChangeRecoMode.ModifiedFinal }"
>
Final print template
</button>
</mat-menu>

View File

@ -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<void> {
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>, motion: ViewMotion): Promise<void> {
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<void> {
// 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<void> {
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
*

View File

@ -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;
}

View File

@ -343,6 +343,19 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
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;