Merge pull request #4304 from MaximilianKrambach/pdfExportComments
export motion comments (pdf) and sequential numbers (pdf, csv)
This commit is contained in:
commit
4c6f907b8c
@ -27,6 +27,14 @@
|
||||
>
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
*ngIf="!isEditMode && comments[section.id]?.comment"
|
||||
(click)="pdfExportSection(section)"
|
||||
matTooltip="{{ 'Export comment' | translate }}"
|
||||
>
|
||||
<mat-icon>picture_as_pdf</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
mat-icon-button
|
||||
*ngIf="isCommentEdited(section)"
|
||||
|
@ -11,6 +11,7 @@ import { OperatorService } from 'app/core/core-services/operator.service';
|
||||
import { MotionComment } from 'app/shared/models/motions/motion-comment';
|
||||
import { ViewMotion } from '../../models/view-motion';
|
||||
import { BaseViewComponent } from 'app/site/base/base-view';
|
||||
import { MotionPdfExportService } from '../../services/motion-pdf-export.service';
|
||||
|
||||
/**
|
||||
* Component for the motion comments view
|
||||
@ -63,6 +64,7 @@ export class MotionCommentsComponent extends BaseViewComponent {
|
||||
* @param commentRepo The repository that handles server communication
|
||||
* @param formBuilder Form builder to handle text editing
|
||||
* @param operator service to get the sections
|
||||
* @param pdfService service to export a comment section to pdf
|
||||
* @param titleService set the browser title
|
||||
* @param translate the translation service
|
||||
* @param matSnackBar showing errors and information
|
||||
@ -71,6 +73,7 @@ export class MotionCommentsComponent extends BaseViewComponent {
|
||||
private commentRepo: MotionCommentSectionRepositoryService,
|
||||
private formBuilder: FormBuilder,
|
||||
private operator: OperatorService,
|
||||
private pdfService: MotionPdfExportService,
|
||||
titleService: Title,
|
||||
translate: TranslateService,
|
||||
matSnackBar: MatSnackBar
|
||||
@ -177,4 +180,13 @@ export class MotionCommentsComponent extends BaseViewComponent {
|
||||
public isCommentEdited(section: ViewMotionCommentSection): boolean {
|
||||
return Object.keys(this.commentForms).includes('' + section.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a direct pdf export of this comment
|
||||
*
|
||||
* @param section
|
||||
*/
|
||||
public pdfExportSection(section: ViewMotionCommentSection): void {
|
||||
this.pdfService.exportComment(section, this.motion);
|
||||
}
|
||||
}
|
||||
|
@ -51,11 +51,25 @@
|
||||
<mat-button-toggle value="category"> <span translate>Category</span> </mat-button-toggle>
|
||||
<mat-button-toggle value="origin"> <span translate>Origin</span> </mat-button-toggle>
|
||||
<mat-button-toggle value="block"> <span translate>Motion block</span> </mat-button-toggle>
|
||||
<mat-button-toggle value="votingResult" #votingResultButton>
|
||||
<mat-button-toggle value="poll" #votingResultButton>
|
||||
<span translate>Voting result</span>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle value="id"><span translate>Sequential number</span></mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<div *ngIf="commentsToExport.length && exportForm.get('format').value === 'pdf'">
|
||||
<p class="toggle-group-head" translate>Comments information</p>
|
||||
<mat-button-toggle-group
|
||||
class="smaller-buttons"
|
||||
multiple
|
||||
formControlName="comments"
|
||||
>
|
||||
<mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id">
|
||||
<span>{{ comment.name }}</span>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
<!-- TODO only if not csv -->
|
||||
</div>
|
||||
|
||||
<br />
|
||||
</div>
|
||||
|
@ -4,6 +4,9 @@ import { MatDialogRef, MatButtonToggle } from '@angular/material';
|
||||
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { LineNumberingMode, ChangeRecoMode } from '../../models/view-motion';
|
||||
import { InfoToExport } from '../../services/motion-pdf.service';
|
||||
import { MotionCommentSectionRepositoryService } from 'app/core/repositories/motions/motion-comment-section-repository.service';
|
||||
import { ViewMotionCommentSection } from '../../models/view-motion-comment-section';
|
||||
|
||||
/**
|
||||
* Dialog component to determine exporting.
|
||||
@ -42,16 +45,23 @@ export class MotionExportDialogComponent implements OnInit {
|
||||
/**
|
||||
* Determine the default meta info to export.
|
||||
*/
|
||||
private defaultInfoToExport = [
|
||||
private defaultInfoToExport: InfoToExport[] = [
|
||||
'submitters',
|
||||
'state',
|
||||
'recommendation',
|
||||
'category',
|
||||
'origin',
|
||||
'block',
|
||||
'votingResult'
|
||||
'polls',
|
||||
'id'
|
||||
];
|
||||
|
||||
/**
|
||||
* @returns a list of availavble commentSections
|
||||
*/
|
||||
public get commentsToExport(): ViewMotionCommentSection[] {
|
||||
return this.commentRepo.getViewModelList();
|
||||
}
|
||||
/**
|
||||
* Hold the default lnMode. Will be set by the constructor.
|
||||
*/
|
||||
@ -82,11 +92,14 @@ export class MotionExportDialogComponent implements OnInit {
|
||||
*
|
||||
* @param formBuilder Creates the export form
|
||||
* @param dialogRef Make the dialog available
|
||||
* @param configService
|
||||
* @param commentRepo
|
||||
*/
|
||||
public constructor(
|
||||
public formBuilder: FormBuilder,
|
||||
public dialogRef: MatDialogRef<MotionExportDialogComponent>,
|
||||
public configService: ConfigService
|
||||
public configService: ConfigService,
|
||||
public commentRepo: MotionCommentSectionRepositoryService
|
||||
) {
|
||||
this.defaultLnMode = this.configService.instant('motions_default_line_numbering');
|
||||
this.defaultCrMode = this.configService.instant('motions_recommendation_text_mode');
|
||||
@ -110,6 +123,8 @@ export class MotionExportDialogComponent implements OnInit {
|
||||
this.exportForm.get('crMode').setValue(this.crMode.Original);
|
||||
this.exportForm.get('crMode').disable();
|
||||
|
||||
this.exportForm.get('comments').disable();
|
||||
|
||||
// remove the selection of "Diff Version" and set it to default or original
|
||||
// TODO: Use this over the disable block logic above when the export service supports more than
|
||||
// just the normal motion text
|
||||
@ -133,6 +148,7 @@ export class MotionExportDialogComponent implements OnInit {
|
||||
// TODO: CSV Issues
|
||||
// this.diffVersionButton.disabled = true;
|
||||
} else if (value === 'pdf') {
|
||||
this.exportForm.get('comments').enable();
|
||||
this.exportForm.get('lnMode').enable();
|
||||
this.exportForm.get('lnMode').setValue(this.defaultLnMode);
|
||||
|
||||
@ -157,7 +173,8 @@ export class MotionExportDialogComponent implements OnInit {
|
||||
lnMode: [this.defaultLnMode],
|
||||
crMode: [this.defaultCrMode],
|
||||
content: [this.defaultContentToExport],
|
||||
metaInfo: [this.defaultInfoToExport]
|
||||
metaInfo: [this.defaultInfoToExport],
|
||||
comments: []
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,8 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
|
||||
result.lnMode,
|
||||
result.crMode,
|
||||
result.content,
|
||||
result.metaInfo
|
||||
result.metaInfo,
|
||||
result.comments
|
||||
);
|
||||
} else if (result.format === 'csv') {
|
||||
this.motionCsvExport.exportMotionList(
|
||||
|
@ -45,6 +45,11 @@ export class MotionPdfCatalogService {
|
||||
* Public entry point to conversion of multiple motions
|
||||
*
|
||||
* @param motions the list of view motions to convert
|
||||
* @param lnMode
|
||||
* @param crMode
|
||||
* @param contentToExport
|
||||
* @param infoToExport
|
||||
* @param commentsToExport
|
||||
* @returns pdfmake doc definition as object
|
||||
*/
|
||||
public motionListToDocDef(
|
||||
@ -52,7 +57,8 @@ export class MotionPdfCatalogService {
|
||||
lnMode?: LineNumberingMode,
|
||||
crMode?: ChangeRecoMode,
|
||||
contentToExport?: string[],
|
||||
infoToExport?: InfoToExport[]
|
||||
infoToExport?: InfoToExport[],
|
||||
commentsToExport?: number[]
|
||||
): object {
|
||||
let doc = [];
|
||||
const motionDocList = [];
|
||||
@ -63,7 +69,8 @@ export class MotionPdfCatalogService {
|
||||
lnMode,
|
||||
crMode,
|
||||
contentToExport,
|
||||
infoToExport
|
||||
infoToExport,
|
||||
commentsToExport
|
||||
);
|
||||
|
||||
// add id field to the first page of a motion to make it findable over TOC
|
||||
|
@ -8,6 +8,7 @@ import { ViewMotion, LineNumberingMode, ChangeRecoMode } from '../models/view-mo
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { MotionPdfCatalogService } from './motion-pdf-catalog.service';
|
||||
import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
|
||||
import { ViewMotionCommentSection } from '../models/view-motion-comment-section';
|
||||
|
||||
/**
|
||||
* Export service to handle various kind of exporting necessities.
|
||||
@ -56,15 +57,24 @@ export class MotionPdfExportService {
|
||||
* @param crMode Change Recommendation Mode
|
||||
* @param contentToExport Determine to determine with text and/or reason
|
||||
* @param infoToExport Determine the meta info to export
|
||||
* @param commentsToExport Comments (by id) to export
|
||||
*/
|
||||
public exportMotionCatalog(
|
||||
motions: ViewMotion[],
|
||||
lnMode?: LineNumberingMode,
|
||||
crMode?: ChangeRecoMode,
|
||||
contentToExport?: string[],
|
||||
infoToExport?: InfoToExport[]
|
||||
infoToExport?: InfoToExport[],
|
||||
commentsToExport?: number[]
|
||||
): void {
|
||||
const doc = this.pdfCatalogService.motionListToDocDef(motions, lnMode, crMode, contentToExport, infoToExport);
|
||||
const doc = this.pdfCatalogService.motionListToDocDef(
|
||||
motions,
|
||||
lnMode,
|
||||
crMode,
|
||||
contentToExport,
|
||||
infoToExport,
|
||||
commentsToExport
|
||||
);
|
||||
const filename = this.translate.instant(this.configService.instant<string>('motions_export_title'));
|
||||
const metadata = {
|
||||
title: filename
|
||||
@ -101,4 +111,21 @@ export class MotionPdfExportService {
|
||||
};
|
||||
this.pdfDocumentService.download(doc, filename, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the given comment with some short information about the
|
||||
* motion the note refers to
|
||||
*
|
||||
* @param comment
|
||||
* @param motion
|
||||
*/
|
||||
public exportComment(comment: ViewMotionCommentSection, motion: ViewMotion): void {
|
||||
const motionComment = motion.getCommentForSection(comment);
|
||||
if (motionComment && motionComment.comment) {
|
||||
const doc = this.motionPdfService.textToDocDef(motionComment.comment, motion, comment.name);
|
||||
const filename = `${motion.identifierOrTitle} - ${comment.name}`;
|
||||
const metadata = { title: filename };
|
||||
this.pdfDocumentService.download(doc, filename, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,21 @@ import { StatuteParagraphRepositoryService } from 'app/core/repositories/motions
|
||||
import { ViewMotion, LineNumberingMode, ChangeRecoMode } from '../models/view-motion';
|
||||
import { ViewUnifiedChange } from '../models/view-unified-change';
|
||||
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
|
||||
import { MotionCommentSectionRepositoryService } from 'app/core/repositories/motions/motion-comment-section-repository.service';
|
||||
|
||||
/**
|
||||
* Type declaring which strings are valid options for metainfos to be exported into a pdf
|
||||
*/
|
||||
export type InfoToExport = 'submitters' | 'state' | 'recommendation' | 'category' | 'block' | 'origin' | 'polls';
|
||||
export type InfoToExport =
|
||||
| 'submitters'
|
||||
| 'state'
|
||||
| 'recommendation'
|
||||
| 'category'
|
||||
| 'block'
|
||||
| 'origin'
|
||||
| 'polls'
|
||||
| 'id'
|
||||
| 'allcomments';
|
||||
|
||||
/**
|
||||
* Converts a motion to pdf. Can be used from the motion detail view or executed on a list of motions
|
||||
@ -43,6 +53,7 @@ export class MotionPdfService {
|
||||
* @param htmlToPdfService To convert HTML text into pdfmake doc def
|
||||
* @param pollService MotionPollService for rendering the polls
|
||||
* @param linenumberingService Line numbers
|
||||
* @param commentRepo MotionCommentSectionRepositoryService to print comments
|
||||
*/
|
||||
public constructor(
|
||||
private translate: TranslateService,
|
||||
@ -52,7 +63,8 @@ export class MotionPdfService {
|
||||
private configService: ConfigService,
|
||||
private htmlToPdfService: HtmlToPdfService,
|
||||
private pollService: MotionPollService,
|
||||
private linenumberingService: LinenumberingService
|
||||
private linenumberingService: LinenumberingService,
|
||||
private commentRepo: MotionCommentSectionRepositoryService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -63,6 +75,7 @@ export class MotionPdfService {
|
||||
* @param crMode determine the used change Recommendation mode
|
||||
* @param contentToExport determine which content is to export. If left out, everything will be exported
|
||||
* @param infoToExport determine which metaInfo to export. If left out, everything will be exported.
|
||||
* @param commentsToExport comments to chose for export. If 'allcomments' is set in infoToExport, this selection will be ignored and all comments exported
|
||||
* @returns doc def for the motion
|
||||
*/
|
||||
public motionToDocDef(
|
||||
@ -70,7 +83,8 @@ export class MotionPdfService {
|
||||
lnMode?: LineNumberingMode,
|
||||
crMode?: ChangeRecoMode,
|
||||
contentToExport?: string[],
|
||||
infoToExport?: InfoToExport[]
|
||||
infoToExport?: InfoToExport[],
|
||||
commentsToExport?: number[]
|
||||
): object {
|
||||
let motionPdfContent = [];
|
||||
|
||||
@ -85,7 +99,8 @@ export class MotionPdfService {
|
||||
}
|
||||
|
||||
const title = this.createTitle(motion);
|
||||
const subtitle = this.createSubtitle(motion);
|
||||
const sequential = !infoToExport || infoToExport.includes('id');
|
||||
const subtitle = this.createSubtitle(motion, sequential);
|
||||
|
||||
motionPdfContent = [title, subtitle];
|
||||
|
||||
@ -106,6 +121,13 @@ export class MotionPdfService {
|
||||
motionPdfContent.push(reason);
|
||||
}
|
||||
|
||||
if (infoToExport && infoToExport.includes('allcomments')) {
|
||||
commentsToExport = this.commentRepo.getViewModelList().map(vm => vm.id);
|
||||
}
|
||||
if (commentsToExport) {
|
||||
motionPdfContent.push(this.createComments(motion, commentsToExport));
|
||||
}
|
||||
|
||||
return motionPdfContent;
|
||||
}
|
||||
|
||||
@ -129,18 +151,17 @@ export class MotionPdfService {
|
||||
* Create the motion subtitle and sequential number part of the doc definition
|
||||
*
|
||||
* @param motion the target motion
|
||||
* @param sequential set to true to include the sequential number
|
||||
* @returns doc def for the subtitle
|
||||
*/
|
||||
private createSubtitle(motion: ViewMotion): object {
|
||||
private createSubtitle(motion: ViewMotion, sequential?: boolean): object {
|
||||
const subtitleLines = [];
|
||||
const exportSequentialNumber = this.configService.instant('motions_export_sequential_number');
|
||||
|
||||
if (exportSequentialNumber) {
|
||||
if (sequential) {
|
||||
subtitleLines.push(`${this.translate.instant('Sequential number')}: ${motion.id}`);
|
||||
}
|
||||
|
||||
if (motion.parent_id) {
|
||||
if (exportSequentialNumber) {
|
||||
if (sequential) {
|
||||
subtitleLines.push(' • ');
|
||||
}
|
||||
subtitleLines.push(
|
||||
@ -257,6 +278,7 @@ export class MotionPdfService {
|
||||
]);
|
||||
}
|
||||
|
||||
// voting results
|
||||
if (motion.motion.polls.length && (!infoToExport || infoToExport.includes('polls'))) {
|
||||
const column1 = [];
|
||||
const column2 = [];
|
||||
@ -634,4 +656,19 @@ export class MotionPdfService {
|
||||
};
|
||||
return [title, subtitle, metaInfo, subHeading, noteContent];
|
||||
}
|
||||
|
||||
private createComments(motion: ViewMotion, comments: number[]): object[] {
|
||||
const result: object[] = [];
|
||||
for (const comment of comments) {
|
||||
const viewComment = this.commentRepo.getViewModel(comment);
|
||||
const section = motion.getCommentForSection(viewComment);
|
||||
if (section && section.comment) {
|
||||
result.push({ text: viewComment.name, style: 'heading3' });
|
||||
result.push({
|
||||
text: this.htmlToPdfService.convertHtml(section.comment)
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -368,13 +368,3 @@ def get_config_variables():
|
||||
group="Motions",
|
||||
subgroup="Export",
|
||||
)
|
||||
|
||||
yield ConfigVariable(
|
||||
name="motions_export_sequential_number",
|
||||
default_value=True,
|
||||
input_type="boolean",
|
||||
label="Include the sequential number in PDF and DOCX",
|
||||
weight=380,
|
||||
group="Motions",
|
||||
subgroup="Export",
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user