Add more option to motion export

Add optional TOC, date and page numbers to the motion export dialog.
Save and restore the last selected entries in the dialog
This commit is contained in:
Sean Engelhardt 2019-07-03 16:42:08 +02:00 committed by Emanuel Schütze
parent e416231ef4
commit f79aa763c2
8 changed files with 225 additions and 173 deletions

View File

@ -7,6 +7,7 @@ import { TranslateService } from '@ngx-translate/core';
import { ConfigService } from './config.service'; import { ConfigService } from './config.service';
import { HttpService } from '../core-services/http.service'; import { HttpService } from '../core-services/http.service';
import { ExportFormData } from 'app/site/motions/modules/motion-list/components/motion-export-dialog/motion-export-dialog.component';
/** /**
* Enumeration to define possible values for the styling. * Enumeration to define possible values for the styling.
@ -177,6 +178,7 @@ export class PdfDocumentService {
private async getStandardPaper( private async getStandardPaper(
documentContent: object, documentContent: object,
metadata?: object, metadata?: object,
exportInfo?: ExportFormData,
imageUrls?: string[], imageUrls?: string[],
customMargins?: [number, number, number, number], customMargins?: [number, number, number, number],
landscape?: boolean landscape?: boolean
@ -197,12 +199,14 @@ export class PdfDocumentService {
fontSize: this.configService.instant('general_export_pdf_fontsize') fontSize: this.configService.instant('general_export_pdf_fontsize')
}, },
header: this.getHeader(customMargins ? [customMargins[0], customMargins[2]] : null), header: this.getHeader(customMargins ? [customMargins[0], customMargins[2]] : null),
// TODO: option for no footer, wherever this can be defined // TODO: option for no footer, wherever this can be defined
footer: (currentPage, pageCount) => { footer: (currentPage, pageCount) => {
return this.getFooter( return this.getFooter(
currentPage, currentPage,
pageCount, pageCount,
customMargins ? [customMargins[0], customMargins[2]] : null customMargins ? [customMargins[0], customMargins[2]] : null,
exportInfo
); );
}, },
info: metadata, info: metadata,
@ -337,14 +341,35 @@ export class PdfDocumentService {
* @param lrMargin optionally overriding the margins * @param lrMargin optionally overriding the margins
* @returns the footer doc definition * @returns the footer doc definition
*/ */
private getFooter(currentPage: number, pageCount: number, lrMargin?: [number, number]): object { private getFooter(
currentPage: number,
pageCount: number,
lrMargin?: [number, number],
exportInfo?: ExportFormData
): object {
const columns = []; const columns = [];
const showPage = exportInfo && exportInfo.pdfOptions ? exportInfo.pdfOptions.includes('page') : true;
const showDate = exportInfo && exportInfo.pdfOptions ? exportInfo.pdfOptions.includes('date') : false;
let logoContainerWidth: string; let logoContainerWidth: string;
let pageNumberPosition: string; let pageNumberPosition: string;
let logoContainerSize: number[]; let logoContainerSize: number[];
const logoFooterLeftUrl = this.configService.instant<any>('logo_pdf_footer_L').path; const logoFooterLeftUrl = this.configService.instant<any>('logo_pdf_footer_L').path;
const logoFooterRightUrl = this.configService.instant<any>('logo_pdf_footer_R').path; const logoFooterRightUrl = this.configService.instant<any>('logo_pdf_footer_R').path;
let footerText = '';
if (showPage) {
footerText += `${currentPage} / ${pageCount}`;
if (showDate) {
footerText += '\n';
}
}
if (showDate) {
footerText += `(${this.translate.instant('Created on')}: ${new Date().toLocaleDateString(
this.translate.currentLang
)})`;
}
// if there is a single logo, give it a lot of space // if there is a single logo, give it a lot of space
if (logoFooterLeftUrl && logoFooterRightUrl) { if (logoFooterLeftUrl && logoFooterRightUrl) {
logoContainerWidth = '20%'; logoContainerWidth = '20%';
@ -377,7 +402,7 @@ export class PdfDocumentService {
// add the page number // add the page number
columns.push({ columns.push({
text: `${currentPage} / ${pageCount}`, text: footerText,
style: 'footerPageNumber', style: 'footerPageNumber',
alignment: pageNumberPosition alignment: pageNumberPosition
}); });
@ -407,8 +432,8 @@ export class PdfDocumentService {
* @param filename the name of the file to use * @param filename the name of the file to use
* @param metadata * @param metadata
*/ */
public download(docDefinition: object, filename: string, metadata?: object): void { public download(docDefinition: object, filename: string, metadata?: object, exportInfo?: ExportFormData): void {
this.getStandardPaper(docDefinition, metadata).then(doc => { this.getStandardPaper(docDefinition, metadata, exportInfo).then(doc => {
this.createPdf(doc, filename); this.createPdf(doc, filename);
}); });
} }
@ -421,7 +446,7 @@ export class PdfDocumentService {
* @param metadata * @param metadata
*/ */
public downloadLandscape(docDefinition: object, filename: string, metadata?: object): void { public downloadLandscape(docDefinition: object, filename: string, metadata?: object): void {
this.getStandardPaper(docDefinition, metadata, null, [50, 80, 50, 75], true).then(doc => { this.getStandardPaper(docDefinition, metadata, null, null, [50, 80, 50, 75], true).then(doc => {
this.createPdf(doc, filename); this.createPdf(doc, filename);
}); });
} }

View File

@ -1389,7 +1389,11 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* Click handler for the pdf button * Click handler for the pdf button
*/ */
public onDownloadPdf(): void { public onDownloadPdf(): void {
this.pdfExport.exportSingleMotion(this.motion, this.lnMode, this.crMode); this.pdfExport.exportSingleMotion(this.motion, {
lnMode: this.lnMode,
crMode: this.crMode,
comments: this.motion.commentSectionIds
});
} }
/** /**

View File

@ -6,9 +6,9 @@
<div> <div>
<p class="toggle-group-head" translate>Format</p> <p class="toggle-group-head" translate>Format</p>
<mat-button-toggle-group class="smaller-buttons" formControlName="format"> <mat-button-toggle-group class="smaller-buttons" formControlName="format">
<mat-button-toggle value="pdf">PDF</mat-button-toggle> <mat-button-toggle [value]="fileFormat.PDF">PDF</mat-button-toggle>
<mat-button-toggle value="csv">CSV</mat-button-toggle> <mat-button-toggle [value]="fileFormat.CSV">CSV</mat-button-toggle>
<mat-button-toggle value="xlsx">XLSX</mat-button-toggle> <mat-button-toggle [value]="fileFormat.XLSX">XLSX</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
@ -54,7 +54,16 @@
</mat-button-toggle> </mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div *ngIf="commentsToExport.length && exportForm.get('format').value === 'pdf'"> <div>
<p class="toggle-group-head" translate>PDF options</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="pdfOptions">
<mat-button-toggle value="toc"> <span translate>Table of Contents</span> </mat-button-toggle>
<mat-button-toggle value="page"> <span translate>Page number</span> </mat-button-toggle>
<mat-button-toggle value="date"> <span translate>Current date</span> </mat-button-toggle>
</mat-button-toggle-group>
</div>
<div *ngIf="commentsToExport.length">
<p class="toggle-group-head" translate>Comments</p> <p class="toggle-group-head" translate>Comments</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="comments"> <mat-button-toggle-group class="smaller-buttons" multiple formControlName="comments">
<mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id"> <mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id">

View File

@ -9,6 +9,30 @@ import { LineNumberingMode, ChangeRecoMode } from 'app/site/motions/models/view-
import { InfoToExport } from 'app/site/motions/services/motion-pdf.service'; import { InfoToExport } from 'app/site/motions/services/motion-pdf.service';
import { ViewMotionCommentSection } from 'app/site/motions/models/view-motion-comment-section'; import { ViewMotionCommentSection } from 'app/site/motions/models/view-motion-comment-section';
import { motionImportExportHeaderOrder, noMetaData } from 'app/site/motions/motion-import-export-order'; import { motionImportExportHeaderOrder, noMetaData } from 'app/site/motions/motion-import-export-order';
import { StorageService } from 'app/core/core-services/storage.service';
import { auditTime } from 'rxjs/operators';
/**
* Determine the possible file format
*/
export enum FileFormat {
PDF = 1,
CSV,
XLSX
}
/**
* Shape the structure of the dialog data
*/
export interface ExportFormData {
format?: FileFormat;
lnMode?: LineNumberingMode;
crMode?: ChangeRecoMode;
content?: string[];
metaInfo?: InfoToExport[];
pdfOptions?: string[];
comments?: number[];
}
/** /**
* Dialog component to determine exporting. * Dialog component to determine exporting.
@ -29,56 +53,37 @@ export class MotionExportDialogComponent implements OnInit {
*/ */
public crMode = ChangeRecoMode; public crMode = ChangeRecoMode;
/**
* to use the format in the template
*/
public fileFormat = FileFormat;
/** /**
* The form that contains the export information. * The form that contains the export information.
*/ */
public exportForm: FormGroup; public exportForm: FormGroup;
/** /**
* determine the default format to export * The default export values in contrast to the restored values
*/ */
private defaultExportFormat = 'pdf'; private defaults: ExportFormData = {
format: FileFormat.PDF,
/** content: ['text', 'reason'],
* Determine the default content to export. pdfOptions: ['toc', 'page'],
*/ metaInfo: ['submitters', 'state', 'recommendation', 'category', 'origin', 'tags', 'motion_block', 'polls', 'id']
private defaultContentToExport = ['text', 'reason']; };
/** /**
* Determine the export order of the meta data * Determine the export order of the meta data
*/ */
public metaInfoExportOrder: string[]; public metaInfoExportOrder: string[];
/**
* Determine the default meta info to export.
*/
private defaultInfoToExport: InfoToExport[] = [
'submitters',
'state',
'recommendation',
'category',
'origin',
'tags',
'motion_block',
'polls',
'id'
];
/** /**
* @returns a list of availavble commentSections * @returns a list of availavble commentSections
*/ */
public get commentsToExport(): ViewMotionCommentSection[] { public get commentsToExport(): ViewMotionCommentSection[] {
return this.commentRepo.getSortedViewModelList(); return this.commentRepo.getSortedViewModelList();
} }
/**
* Hold the default lnMode. Will be set by the constructor.
*/
private defaultLnMode: LineNumberingMode;
/**
* Hold the default crMode. Will be set by the constructor.
*/
private defaultCrMode: ChangeRecoMode;
/** /**
* To deactivate the export-as-diff button * To deactivate the export-as-diff button
@ -87,7 +92,7 @@ export class MotionExportDialogComponent implements OnInit {
public diffVersionButton: MatButtonToggle; public diffVersionButton: MatButtonToggle;
/** /**
* To deactivate the export-as-diff button * To deactivate the voting result button
*/ */
@ViewChild('votingResultButton', { static: true }) @ViewChild('votingResultButton', { static: true })
public votingResultButton: MatButtonToggle; public votingResultButton: MatButtonToggle;
@ -107,10 +112,11 @@ export class MotionExportDialogComponent implements OnInit {
public formBuilder: FormBuilder, public formBuilder: FormBuilder,
public dialogRef: MatDialogRef<MotionExportDialogComponent>, public dialogRef: MatDialogRef<MotionExportDialogComponent>,
public configService: ConfigService, public configService: ConfigService,
public commentRepo: MotionCommentSectionRepositoryService public commentRepo: MotionCommentSectionRepositoryService,
private store: StorageService
) { ) {
this.defaultLnMode = this.configService.instant('motions_default_line_numbering'); this.defaults.lnMode = this.configService.instant('motions_default_line_numbering');
this.defaultCrMode = this.configService.instant('motions_recommendation_text_mode'); this.defaults.crMode = this.configService.instant('motions_recommendation_text_mode');
// Get the export order, exclude everything that does not count as meta-data // Get the export order, exclude everything that does not count as meta-data
this.metaInfoExportOrder = motionImportExportHeaderOrder.filter(metaData => { this.metaInfoExportOrder = motionImportExportHeaderOrder.filter(metaData => {
return !noMetaData.some(noMeta => metaData === noMeta); return !noMetaData.some(noMeta => metaData === noMeta);
@ -123,67 +129,83 @@ export class MotionExportDialogComponent implements OnInit {
* Observes the form for changes to react dynamically * Observes the form for changes to react dynamically
*/ */
public ngOnInit(): void { public ngOnInit(): void {
this.exportForm.get('format').valueChanges.subscribe((value: string) => { this.exportForm.valueChanges.pipe(auditTime(500)).subscribe((value: ExportFormData) => {
// disable content for xslx this.store.set('motion_export_selection', value);
if (value === 'xlsx') { });
// disable the content selection
this.exportForm.get('content').disable(); this.exportForm.get('format').valueChanges.subscribe((value: FileFormat) => this.onFormatChange(value));
// remove the selection of "content"
this.exportForm.get('content').setValue(null);
} else {
this.exportForm.get('content').enable();
} }
if (value === 'csv' || value === 'xlsx') { /**
// disable and deselect "lnMode" * React to changes on the file format
this.exportForm.get('lnMode').setValue(this.lnMode.None); * @param format
this.exportForm.get('lnMode').disable(); */
private onFormatChange(format: FileFormat): void {
// XLSX cannot have "content"
if (format === FileFormat.XLSX) {
this.disableControl('content');
} else {
this.enableControl('content');
}
// disable and deselect "Change Reco Mode" if (format === FileFormat.CSV || format === FileFormat.XLSX) {
// TODO: The current implementation of the motion csv export does not consider anything else than this.disableControl('lnMode');
// the "normal" motion.text, therefore this is disabled for now this.disableControl('crMode');
this.exportForm.get('crMode').setValue(this.crMode.Original); this.disableControl('comments');
this.exportForm.get('crMode').disable(); this.disableControl('pdfOptions');
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
// if (this.exportForm.get('crMode').value === this.crMode.Diff) {
// if (this.defaultCrMode === this.crMode.Diff) {
// this.exportForm.get('crMode').setValue(this.crMode.Original);
// } else {
// this.exportForm.get('crMode').setValue(this.defaultCrMode);
// }
// }
// remove the selection of "votingResult" // remove the selection of "votingResult"
let metaInfoVal: string[] = this.exportForm.get('metaInfo').value; let metaInfoVal: string[] = this.exportForm.get('metaInfo').value;
if (metaInfoVal) {
metaInfoVal = metaInfoVal.filter(info => { metaInfoVal = metaInfoVal.filter(info => {
return info !== 'polls'; return info !== 'polls';
}); });
this.exportForm.get('metaInfo').setValue(metaInfoVal); this.exportForm.get('metaInfo').setValue(metaInfoVal);
// disable "Diff Version" and "Voting Result"
this.votingResultButton.disabled = true;
// 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);
// TODO: Temporarily necessary until CSV has been fixed
this.exportForm.get('crMode').enable();
this.exportForm.get('crMode').setValue(this.defaultCrMode);
// enable "Diff Version" and "Voting Result"
this.votingResultButton.disabled = false;
// TODO: Temporarily disabled. Will be required after CSV fixes
// this.diffVersionButton.disabled = false;
} }
}); this.votingResultButton.disabled = true;
}
if (format === FileFormat.PDF) {
this.enableControl('lnMode');
this.enableControl('crMode');
this.enableControl('comments');
this.enableControl('pdfOptions');
this.votingResultButton.disabled = false;
}
}
/**
* Helper function to easier enable a control
* @param name
*/
private enableControl(name: string): void {
this.exportForm.get(name).enable();
}
/**
* Helper function to easier disable a control
*
* @param name
*/
private disableControl(name: string): void {
this.exportForm.get(name).disable();
this.exportForm.get(name).setValue(this.getOffState(name));
}
/**
* Determine what "off means in certain states"
*
* @param control
*/
private getOffState(control: string): string | null {
switch (control) {
case 'lnMode':
return this.lnMode.None;
case 'crMode':
return this.crMode.Original;
default:
return null;
}
} }
/** /**
@ -191,13 +213,23 @@ export class MotionExportDialogComponent implements OnInit {
*/ */
public createForm(): void { public createForm(): void {
this.exportForm = this.formBuilder.group({ this.exportForm = this.formBuilder.group({
format: [this.defaultExportFormat], format: [],
lnMode: [this.defaultLnMode], lnMode: [],
crMode: [this.defaultCrMode], crMode: [],
content: [this.defaultContentToExport], content: [],
metaInfo: [this.defaultInfoToExport], metaInfo: [],
pdfOptions: [],
comments: [] comments: []
}); });
// restore selection or set default
this.store.get<ExportFormData>('motion_export_selection').then(restored => {
if (!!restored) {
this.exportForm.patchValue(restored);
} else {
this.exportForm.patchValue(this.defaults);
}
});
} }
/** /**

View File

@ -15,7 +15,11 @@ import { MotionRepositoryService } from 'app/core/repositories/motions/motion-re
import { TagRepositoryService } from 'app/core/repositories/tags/tag-repository.service'; import { TagRepositoryService } from 'app/core/repositories/tags/tag-repository.service';
import { ViewTag } from 'app/site/tags/models/view-tag'; import { ViewTag } from 'app/site/tags/models/view-tag';
import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service'; import { WorkflowRepositoryService } from 'app/core/repositories/motions/workflow-repository.service';
import { MotionExportDialogComponent } from '../motion-export-dialog/motion-export-dialog.component'; import {
MotionExportDialogComponent,
FileFormat,
ExportFormData
} from '../motion-export-dialog/motion-export-dialog.component';
import { ViewMotion, LineNumberingMode, ChangeRecoMode } from 'app/site/motions/models/view-motion'; import { ViewMotion, LineNumberingMode, ChangeRecoMode } from 'app/site/motions/models/view-motion';
import { ViewWorkflow } from 'app/site/motions/models/view-workflow'; import { ViewWorkflow } from 'app/site/motions/models/view-workflow';
import { ViewCategory } from 'app/site/motions/models/view-category'; import { ViewCategory } from 'app/site/motions/models/view-category';
@ -302,19 +306,12 @@ export class MotionListComponent extends BaseListViewComponent<ViewMotion> imple
data: this.dataSource data: this.dataSource
}); });
exportDialogRef.afterClosed().subscribe((result: any) => { exportDialogRef.afterClosed().subscribe((exportInfo: ExportFormData) => {
if (result && result.format) { if (exportInfo && exportInfo.format) {
const data = this.isMultiSelect ? this.selectedRows : this.dataSource.source; const data = this.isMultiSelect ? this.selectedRows : this.dataSource.source;
if (result.format === 'pdf') { if (exportInfo.format === FileFormat.PDF) {
try { try {
this.pdfExport.exportMotionCatalog( this.pdfExport.exportMotionCatalog(data, exportInfo);
data,
result.lnMode,
result.crMode,
result.content,
result.metaInfo,
result.comments
);
} catch (err) { } catch (err) {
if (err instanceof PdfError) { if (err instanceof PdfError) {
this.raiseError(err.message); this.raiseError(err.message);
@ -322,10 +319,14 @@ export class MotionListComponent extends BaseListViewComponent<ViewMotion> imple
throw err; throw err;
} }
} }
} else if (result.format === 'csv') { } else if (exportInfo.format === FileFormat.CSV) {
this.motionCsvExport.exportMotionList(data, [...result.content, ...result.metaInfo], result.crMode); this.motionCsvExport.exportMotionList(
} else if (result.format === 'xlsx') { data,
this.motionXlsxExport.exportMotionList(data, result.metaInfo); [...exportInfo.content, ...exportInfo.metaInfo],
exportInfo.crMode
);
} else if (exportInfo.format === FileFormat.XLSX) {
this.motionXlsxExport.exportMotionList(data, exportInfo.metaInfo);
} }
} }
}); });
@ -399,11 +400,12 @@ export class MotionListComponent extends BaseListViewComponent<ViewMotion> imple
* Directly export all motions as pdf, using the current default config settings * Directly export all motions as pdf, using the current default config settings
*/ */
public directPdfExport(): void { public directPdfExport(): void {
this.pdfExport.exportMotionCatalog( const lnMode = this.configService.instant<string>('motions_default_line_numbering') as LineNumberingMode;
this.dataSource.source, const crMode = this.configService.instant<string>('motions_recommendation_text_mode') as ChangeRecoMode;
this.configService.instant<string>('motions_default_line_numbering') as LineNumberingMode, this.pdfExport.exportMotionCatalog(this.dataSource.source, {
this.configService.instant<string>('motions_recommendation_text_mode') as ChangeRecoMode lnMode: lnMode,
); crMode: crMode
});
} }
/** /**

View File

@ -5,11 +5,12 @@ import { TranslateService } from '@ngx-translate/core';
import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service'; import { CategoryRepositoryService } from 'app/core/repositories/motions/category-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { MotionPdfService, InfoToExport } from './motion-pdf.service'; import { MotionPdfService } from './motion-pdf.service';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service'; import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { PdfError, PdfDocumentService, StyleType, BorderType } from 'app/core/ui-services/pdf-document.service'; import { PdfError, PdfDocumentService, StyleType, BorderType } from 'app/core/ui-services/pdf-document.service';
import { ViewCategory } from '../models/view-category'; import { ViewCategory } from '../models/view-category';
import { ViewMotion, LineNumberingMode, ChangeRecoMode } from '../models/view-motion'; import { ViewMotion } from '../models/view-motion';
import { ExportFormData } from '../modules/motion-list/components/motion-export-dialog/motion-export-dialog.component';
/** /**
* Service to export a list of motions. * Service to export a list of motions.
@ -55,27 +56,13 @@ export class MotionPdfCatalogService {
* @param commentsToExport * @param commentsToExport
* @returns pdfmake doc definition as object * @returns pdfmake doc definition as object
*/ */
public motionListToDocDef( public motionListToDocDef(motions: ViewMotion[], exportInfo: ExportFormData): object {
motions: ViewMotion[],
lnMode?: LineNumberingMode,
crMode?: ChangeRecoMode,
contentToExport?: string[],
infoToExport?: InfoToExport[],
commentsToExport?: number[]
): object {
let doc = []; let doc = [];
const motionDocList = []; const motionDocList = [];
for (let motionIndex = 0; motionIndex < motions.length; ++motionIndex) { for (let motionIndex = 0; motionIndex < motions.length; ++motionIndex) {
try { try {
const motionDocDef: any = this.motionPdfService.motionToDocDef( const motionDocDef: any = this.motionPdfService.motionToDocDef(motions[motionIndex], exportInfo);
motions[motionIndex],
lnMode,
crMode,
contentToExport,
infoToExport,
commentsToExport
);
// add id field to the first page of a motion to make it findable over TOC // add id field to the first page of a motion to make it findable over TOC
motionDocDef[0].id = `${motions[motionIndex].id}`; motionDocDef[0].id = `${motions[motionIndex].id}`;
@ -95,7 +82,7 @@ export class MotionPdfCatalogService {
} }
// print extra data (title, preamble, categories, toc) only if there are more than 1 motion // print extra data (title, preamble, categories, toc) only if there are more than 1 motion
if (motions.length > 1) { if (motions.length > 1 && (!exportInfo.pdfOptions || exportInfo.pdfOptions.includes('toc'))) {
doc.push( doc.push(
this.pdfService.createTitle('motions_export_title'), this.pdfService.createTitle('motions_export_title'),
this.pdfService.createPreamble('motions_export_preamble'), this.pdfService.createPreamble('motions_export_preamble'),

View File

@ -2,13 +2,14 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { MotionPdfService, InfoToExport } from './motion-pdf.service'; import { MotionPdfService } from './motion-pdf.service';
import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service'; import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service';
import { ViewMotion, LineNumberingMode, ChangeRecoMode } from '../models/view-motion'; import { ViewMotion } from '../models/view-motion';
import { ConfigService } from 'app/core/ui-services/config.service'; import { ConfigService } from 'app/core/ui-services/config.service';
import { MotionPdfCatalogService } from './motion-pdf-catalog.service'; import { MotionPdfCatalogService } from './motion-pdf-catalog.service';
import { PersonalNoteContent } from 'app/shared/models/users/personal-note'; import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
import { ViewMotionCommentSection } from '../models/view-motion-comment-section'; import { ViewMotionCommentSection } from '../models/view-motion-comment-section';
import { ExportFormData } from '../modules/motion-list/components/motion-export-dialog/motion-export-dialog.component';
/** /**
* Export service to handle various kind of exporting necessities. * Export service to handle various kind of exporting necessities.
@ -40,8 +41,8 @@ export class MotionPdfExportService {
* @param lnMode the desired line numbering mode * @param lnMode the desired line numbering mode
* @param crMode the desired change recomendation mode * @param crMode the desired change recomendation mode
*/ */
public exportSingleMotion(motion: ViewMotion, lnMode?: LineNumberingMode, crMode?: ChangeRecoMode): void { public exportSingleMotion(motion: ViewMotion, exportInfo?: ExportFormData): void {
const doc = this.motionPdfService.motionToDocDef(motion, lnMode, crMode); const doc = this.motionPdfService.motionToDocDef(motion, exportInfo);
const filename = `${this.translate.instant('Motion')} ${motion.identifierOrTitle}`; const filename = `${this.translate.instant('Motion')} ${motion.identifierOrTitle}`;
const metadata = { const metadata = {
title: filename title: filename
@ -59,27 +60,13 @@ export class MotionPdfExportService {
* @param infoToExport Determine the meta info to export * @param infoToExport Determine the meta info to export
* @param commentsToExport Comments (by id) to export * @param commentsToExport Comments (by id) to export
*/ */
public exportMotionCatalog( public exportMotionCatalog(motions: ViewMotion[], exportInfo: ExportFormData): void {
motions: ViewMotion[], const doc = this.pdfCatalogService.motionListToDocDef(motions, exportInfo);
lnMode?: LineNumberingMode,
crMode?: ChangeRecoMode,
contentToExport?: string[],
infoToExport?: InfoToExport[],
commentsToExport?: number[]
): void {
const doc = this.pdfCatalogService.motionListToDocDef(
motions,
lnMode,
crMode,
contentToExport,
infoToExport,
commentsToExport
);
const filename = this.translate.instant(this.configService.instant<string>('motions_export_title')); const filename = this.translate.instant(this.configService.instant<string>('motions_export_title'));
const metadata = { const metadata = {
title: filename title: filename
}; };
this.pdfDocumentService.download(doc, filename, metadata); this.pdfDocumentService.download(doc, filename, metadata, exportInfo);
} }
/** /**

View File

@ -17,6 +17,7 @@ import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service';
import { ViewMotionAmendedParagraph } from '../models/view-motion-amended-paragraph'; import { ViewMotionAmendedParagraph } from '../models/view-motion-amended-paragraph';
import { ViewMotionChangeRecommendation } from '../models/view-motion-change-recommendation'; import { ViewMotionChangeRecommendation } from '../models/view-motion-change-recommendation';
import { ViewUnifiedChange, ViewUnifiedChangeType } from 'app/shared/models/motions/view-unified-change'; import { ViewUnifiedChange, ViewUnifiedChangeType } from 'app/shared/models/motions/view-unified-change';
import { ExportFormData } from '../modules/motion-list/components/motion-export-dialog/motion-export-dialog.component';
/** /**
* Type declaring which strings are valid options for metainfos to be exported into a pdf * Type declaring which strings are valid options for metainfos to be exported into a pdf
@ -91,14 +92,13 @@ export class MotionPdfService {
* @param commentsToExport comments to chose for export. If 'allcomments' is set in infoToExport, this selection will be ignored and all comments 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 * @returns doc def for the motion
*/ */
public motionToDocDef( public motionToDocDef(motion: ViewMotion, exportInfo?: ExportFormData): object {
motion: ViewMotion, let lnMode = exportInfo && exportInfo.lnMode ? exportInfo.lnMode : null;
lnMode?: LineNumberingMode, let crMode = exportInfo && exportInfo.crMode ? exportInfo.crMode : null;
crMode?: ChangeRecoMode, const infoToExport = exportInfo ? exportInfo.metaInfo : null;
contentToExport?: string[], const contentToExport = exportInfo ? exportInfo.content : null;
infoToExport?: InfoToExport[], let commentsToExport = exportInfo ? exportInfo.comments : null;
commentsToExport?: number[]
): object {
// get the line length from the config // get the line length from the config
const lineLength = this.configService.instant<number>('motions_line_length'); const lineLength = this.configService.instant<number>('motions_line_length');
// whether to append checkboxes to follow the recommendation or not // whether to append checkboxes to follow the recommendation or not
@ -178,7 +178,13 @@ export class MotionPdfService {
const changedTitle = this.changeRecoRepo.getTitleWithChanges(motion.title, titleChange, crMode); const changedTitle = this.changeRecoRepo.getTitleWithChanges(motion.title, titleChange, crMode);
const identifier = motion.identifier ? ' ' + motion.identifier : ''; const identifier = motion.identifier ? ' ' + motion.identifier : '';
const title = `${this.translate.instant('Motion')} ${identifier}: ${changedTitle}`; const pageSize = this.configService.instant('general_export_pdf_pagesize');
let title = '';
if (pageSize === 'A4') {
title += `${this.translate.instant('Motion')} `;
}
title += `${identifier}: ${changedTitle}`;
return { return {
text: title, text: title,