Merge pull request #4189 from tsiegleauq/os3-motion-export-dialog

Add Motion Export dialog
This commit is contained in:
Emanuel Schütze 2019-01-28 10:34:43 +01:00 committed by GitHub
commit 56ff765708
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 441 additions and 95 deletions

View File

@ -9,7 +9,7 @@ import { ConfigService } from './config.service';
* Defines a csv column with a property of the model and an optional label. If this is not given, the * Defines a csv column with a property of the model and an optional label. If this is not given, the
* translated and capitalized property name is used. * translated and capitalized property name is used.
*/ */
interface CsvColumnDefinitionProperty<T> { export interface CsvColumnDefinitionProperty<T> {
label?: string; label?: string;
property: keyof T; property: keyof T;
} }

View File

@ -0,0 +1,68 @@
<h1 mat-dialog-title>{{ 'Export motions' | translate }}</h1>
<form [formGroup]="exportForm">
<!-- Content -->
<div mat-dialog-content>
<div>
<p class="toggle-group-head" translate>Format</p>
<mat-button-toggle-group formControlName="format">
<mat-button-toggle value="pdf">PDF</mat-button-toggle>
<mat-button-toggle value="csv">CSV</mat-button-toggle>
</mat-button-toggle-group>
</div>
<div>
<p class="toggle-group-head" translate>Line numbering</p>
<mat-button-toggle-group formControlName="lnMode">
<mat-button-toggle [value]="lnMode.None"> <span translate>None</span> </mat-button-toggle>
<mat-button-toggle [value]="lnMode.Inside"> <span translate>Inline</span> </mat-button-toggle>
<mat-button-toggle [value]="lnMode.Outside"> <span translate>Outside</span> </mat-button-toggle>
</mat-button-toggle-group>
</div>
<div>
<p class="toggle-group-head" translate>Change recommendations</p>
<mat-button-toggle-group formControlName="crMode">
<mat-button-toggle [value]="crMode.Original">
<span translate>Original version</span>
</mat-button-toggle>
<mat-button-toggle [value]="crMode.Changed"> <span translate>Changed version</span> </mat-button-toggle>
<mat-button-toggle [value]="crMode.Diff" #diffVersionButton>
<span translate>Diff version</span>
</mat-button-toggle>
<mat-button-toggle [value]="crMode.Final"> <span translate>Final version</span> </mat-button-toggle>
</mat-button-toggle-group>
</div>
<div>
<p class="toggle-group-head" translate>Content</p>
<mat-button-toggle-group multiple formControlName="content">
<mat-button-toggle value="text"> <span translate>Text</span> </mat-button-toggle>
<mat-button-toggle value="reason"> <span translate>Reason</span> </mat-button-toggle>
</mat-button-toggle-group>
</div>
<div>
<p class="toggle-group-head" translate>Meta information</p>
<mat-button-toggle-group multiple formControlName="metaInfo">
<mat-button-toggle value="submitters"> <span translate>Submitters</span> </mat-button-toggle>
<mat-button-toggle value="state" #stateButton> <span translate>State</span> </mat-button-toggle>
<mat-button-toggle value="recommendation" #recommendationButton> <span translate>Recommendation</span> </mat-button-toggle>
<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> <span translate>Voting Result</span> </mat-button-toggle>
</mat-button-toggle-group>
</div>
<br />
</div>
<!-- Action buttons -->
<div mat-dialog-actions>
<button mat-button type="button" color="primary" [mat-dialog-close]="exportForm.value">
<span translate>Export</span>
</button>
<button mat-button type="button" (click)="onCloseClick()"><span translate>Cancel</span></button>
</div>
</form>

View File

@ -0,0 +1,3 @@
.toggle-group-head {
margin-bottom: 0;
}

View File

@ -0,0 +1,28 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MotionExportDialogComponent } from './motion-export-dialog.component';
import { E2EImportsModule } from 'e2e-imports.module';
import { MatDialogRef } from '@angular/material';
describe('MotionExportDialogComponent', () => {
let component: MotionExportDialogComponent;
let fixture: ComponentFixture<MotionExportDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [E2EImportsModule],
declarations: [MotionExportDialogComponent],
providers: [{ provide: MatDialogRef, useValue: {} }]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MotionExportDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,186 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { MatDialogRef, MatButtonToggle } from '@angular/material';
import { ConfigService } from 'app/core/services/config.service';
import { LineNumberingMode, ChangeRecoMode } from '../../models/view-motion';
/**
* Dialog component to determine exporting.
*/
@Component({
selector: 'os-motion-export-dialog',
templateUrl: './motion-export-dialog.component.html',
styleUrls: ['./motion-export-dialog.component.scss']
})
export class MotionExportDialogComponent implements OnInit {
/**
* For using the enum constants from the template.
*/
public lnMode = LineNumberingMode;
/**
* For using the enum constants from the template.
*/
public crMode = ChangeRecoMode;
/**
* The form that contains the export information.
*/
public exportForm: FormGroup;
/**
* determine the default format to export
*/
private defaultExportFormat = 'pdf';
/**
* Determine the default content to export.
*/
private defaultContentToExport = ['text', 'reason'];
/**
* Determine the default meta info to export.
*/
private defaultInfoToExport = [
'submitters',
'state',
'recommendation',
'category',
'origin',
'block',
'votingResult'
];
/**
* 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
*/
@ViewChild('diffVersionButton')
public diffVersionButton: MatButtonToggle;
/**
* To deactivate the export-as-diff button
*/
@ViewChild('votingResultButton')
public votingResultButton: MatButtonToggle;
/**
* To deactivate the state button
*/
@ViewChild('stateButton')
public stateButton: MatButtonToggle;
/**
* To deactivate the state button
*/
@ViewChild('recommendationButton')
public recommendationButton: MatButtonToggle;
/**
* Constructor
* Sets the default values for the lineNumberingMode and changeRecoMode and creates the form.
* This uses "instant" over observables to prevent on-fly-changes by auto update while
* the dialog is open.
*
* @param formBuilder Creates the export form
* @param dialogRef Make the dialog available
*/
public constructor(
public formBuilder: FormBuilder,
public dialogRef: MatDialogRef<MotionExportDialogComponent>,
public configService: ConfigService
) {
this.defaultLnMode = this.configService.instant('motions_default_line_numbering');
this.defaultCrMode = this.configService.instant('motions_recommendation_text_mode');
this.createForm();
}
/**
* Init.
* Observes the form for changes to react dynamically
*/
public ngOnInit(): void {
this.exportForm.get('format').valueChanges.subscribe((value: string) => {
if (value === 'csv') {
// disable and deselect "lnMode"
this.exportForm.get('lnMode').setValue(this.lnMode.None);
this.exportForm.get('lnMode').disable();
// disable and deselect "Change Reco Mode"
// TODO: The current implementation of the motion csv export does not consider anything else than
// the "normal" motion.text, therefore this is disabled for now
this.exportForm.get('crMode').setValue(this.crMode.Original);
this.exportForm.get('crMode').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", "state" and "recommendation"
let metaInfoVal: string[] = this.exportForm.get('metaInfo').value;
metaInfoVal = metaInfoVal.filter(info => {
return info !== 'votingResult' && info !== 'state' && info !== 'recommendation';
});
this.exportForm.get('metaInfo').setValue(metaInfoVal);
// disable "Diff Version", "Voting Result", "State" and "Recommendation"
this.votingResultButton.disabled = true;
this.stateButton.disabled = true;
this.recommendationButton.disabled = true;
// TODO: CSV Issues
// this.diffVersionButton.disabled = true;
} else if (value === 'pdf') {
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", "Voting Result", "State" and "Recommendation"
this.votingResultButton.disabled = false;
this.stateButton.disabled = false;
this.recommendationButton.disabled = false;
// TODO: Temporarily disabled. Will be required after CSV fixes
// this.diffVersionButton.disabled = false;
}
});
}
/**
* Creates the form with default values
*/
public createForm(): void {
this.exportForm = this.formBuilder.group({
format: [this.defaultExportFormat],
lnMode: [this.defaultLnMode],
crMode: [this.defaultCrMode],
content: [this.defaultContentToExport],
metaInfo: [this.defaultInfoToExport]
});
}
/**
* Just close the dialog
*/
public onCloseClick(): void {
this.dialogRef.close();
}
}

View File

@ -174,13 +174,9 @@
<mat-icon>local_offer</mat-icon> <mat-icon>local_offer</mat-icon>
<span translate>Tags</span> <span translate>Tags</span>
</button> </button>
<button mat-menu-item (click)="csvExportMotionList()"> <button mat-menu-item (click)="openExportDialog()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export as CSV</span> <span translate>Export</span><span>&nbsp;...</span>
</button>
<button mat-menu-item (click)="onExportAsPdf()">
<mat-icon>picture_as_pdf</mat-icon>
<span translate>Export all as PDF</span>
</button> </button>
<button mat-menu-item routerLink="import"> <button mat-menu-item routerLink="import">
<mat-icon>save_alt</mat-icon> <mat-icon>save_alt</mat-icon>

View File

@ -1,13 +1,14 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { MatSnackBar, MatDialog } from '@angular/material';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CategoryRepositoryService } from '../../services/category-repository.service'; import { CategoryRepositoryService } from '../../services/category-repository.service';
import { ConfigService } from '../../../../core/services/config.service'; import { ConfigService } from '../../../../core/services/config.service';
import { ListViewBaseComponent } from '../../../base/list-view-base'; import { ListViewBaseComponent } from '../../../base/list-view-base';
import { LocalPermissionsService } from '../../services/local-permissions.service'; import { LocalPermissionsService } from '../../services/local-permissions.service';
import { MatSnackBar } from '@angular/material';
import { MotionBlockRepositoryService } from '../../services/motion-block-repository.service'; import { MotionBlockRepositoryService } from '../../services/motion-block-repository.service';
import { MotionCsvExportService } from '../../services/motion-csv-export.service'; import { MotionCsvExportService } from '../../services/motion-csv-export.service';
import { MotionFilterListService } from '../../services/motion-filter-list.service'; import { MotionFilterListService } from '../../services/motion-filter-list.service';
@ -23,6 +24,7 @@ import { ViewWorkflow } from '../../models/view-workflow';
import { WorkflowState } from '../../../../shared/models/motions/workflow-state'; import { WorkflowState } from '../../../../shared/models/motions/workflow-state';
import { WorkflowRepositoryService } from '../../services/workflow-repository.service'; import { WorkflowRepositoryService } from '../../services/workflow-repository.service';
import { MotionPdfExportService } from '../../services/motion-pdf-export.service'; import { MotionPdfExportService } from '../../services/motion-pdf-export.service';
import { MotionExportDialogComponent } from '../motion-export-dialog/motion-export-dialog.component';
/** /**
* Component that displays all the motions in a Table using DataSource. * Component that displays all the motions in a Table using DataSource.
@ -96,6 +98,7 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
private motionRepo: MotionRepositoryService, private motionRepo: MotionRepositoryService,
private motionCsvExport: MotionCsvExportService, private motionCsvExport: MotionCsvExportService,
private pdfExport: MotionPdfExportService, private pdfExport: MotionPdfExportService,
private dialog: MatDialog,
public multiselectService: MotionMultiselectService, public multiselectService: MotionMultiselectService,
public sortService: MotionSortListService, public sortService: MotionSortListService,
public filterService: MotionFilterListService, public filterService: MotionFilterListService,
@ -189,17 +192,29 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
} }
/** /**
* Export all motions as CSV * Opens the export dialog
*/ */
public csvExportMotionList(): void { public openExportDialog(): void {
this.motionCsvExport.exportMotionList(this.dataSource.data); const exportDialogRef = this.dialog.open(MotionExportDialogComponent, {
} width: '750px',
data: this.dataSource
});
/** exportDialogRef.afterClosed().subscribe((result: any) => {
* Exports motions as PDF. if (result && result.format) {
*/ if (result.format === 'pdf') {
public onExportAsPdf(): void { this.pdfExport.exportMotionCatalog(
this.pdfExport.exportMotionCatalog(this.dataSource.data); this.dataSource.data,
result.lnMode,
result.crMode,
result.content,
result.metaInfo
);
} else if (result.format === 'csv') {
this.motionCsvExport.exportMotionList(this.dataSource.data, result.content, result.metaInfo);
}
}
});
} }
/** /**

View File

@ -22,6 +22,7 @@ import { MotionImportListComponent } from './components/motion-import-list/motio
import { ManageSubmittersComponent } from './components/manage-submitters/manage-submitters.component'; import { ManageSubmittersComponent } from './components/manage-submitters/manage-submitters.component';
import { MotionPollComponent } from './components/motion-poll/motion-poll.component'; import { MotionPollComponent } from './components/motion-poll/motion-poll.component';
import { MotionPollDialogComponent } from './components/motion-poll/motion-poll-dialog.component'; import { MotionPollDialogComponent } from './components/motion-poll/motion-poll-dialog.component';
import { MotionExportDialogComponent } from './components/motion-export-dialog/motion-export-dialog.component';
@NgModule({ @NgModule({
imports: [CommonModule, MotionsRoutingModule, SharedModule], imports: [CommonModule, MotionsRoutingModule, SharedModule],
@ -44,7 +45,8 @@ import { MotionPollDialogComponent } from './components/motion-poll/motion-poll-
MotionImportListComponent, MotionImportListComponent,
ManageSubmittersComponent, ManageSubmittersComponent,
MotionPollComponent, MotionPollComponent,
MotionPollDialogComponent MotionPollDialogComponent,
MotionExportDialogComponent
], ],
entryComponents: [ entryComponents: [
MotionChangeRecommendationComponent, MotionChangeRecommendationComponent,
@ -54,7 +56,8 @@ import { MotionPollDialogComponent } from './components/motion-poll/motion-poll-
MetaTextBlockComponent, MetaTextBlockComponent,
PersonalNoteComponent, PersonalNoteComponent,
ManageSubmittersComponent, ManageSubmittersComponent,
MotionPollDialogComponent MotionPollDialogComponent,
MotionExportDialogComponent
] ]
}) })
export class MotionsModule {} export class MotionsModule {}

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CsvExportService } from 'app/core/services/csv-export.service'; import { CsvExportService, CsvColumnDefinitionProperty } from 'app/core/services/csv-export.service';
import { ViewMotion } from '../models/view-motion'; import { ViewMotion } from '../models/view-motion';
import { FileExportService } from 'app/core/services/file-export.service'; import { FileExportService } from 'app/core/services/file-export.service';
@ -29,21 +29,16 @@ export class MotionCsvExportService {
* Export all motions as CSV * Export all motions as CSV
* *
* @param motions Motions to export * @param motions Motions to export
* @param contentToExport content properties to export
* @param infoToExport meta info to export
*/ */
public exportMotionList(motions: ViewMotion[]): void { public exportMotionList(motions: ViewMotion[], contentToExport: string[], infoToExport: string[]): void {
this.csvExport.export( const propertyList = ['identifier', 'title'].concat(contentToExport, infoToExport);
motions, const exportProperties: CsvColumnDefinitionProperty<ViewMotion>[] = propertyList.map(option => {
[ return { property: option } as CsvColumnDefinitionProperty<ViewMotion>;
{ property: 'identifier' }, });
{ property: 'title' },
{ property: 'text' }, this.csvExport.export(motions, exportProperties, this.translate.instant('Motions') + '.csv');
{ property: 'reason' },
{ property: 'submitters' },
{ property: 'category' },
{ property: 'origin' }
],
this.translate.instant('Motions') + '.csv'
);
} }
/** /**

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ViewMotion } from '../models/view-motion'; import { ViewMotion, LineNumberingMode, ChangeRecoMode } from '../models/view-motion';
import { MotionPdfService } from './motion-pdf.service'; import { MotionPdfService } from './motion-pdf.service';
import { ConfigService } from 'app/core/services/config.service'; import { ConfigService } from 'app/core/services/config.service';
import { Category } from 'app/shared/models/motions/category'; import { Category } from 'app/shared/models/motions/category';
@ -47,12 +47,24 @@ export class MotionPdfCatalogService {
* @param motions the list of view motions to convert * @param motions the list of view motions to convert
* @returns pdfmake doc definition as object * @returns pdfmake doc definition as object
*/ */
public motionListToDocDef(motions: ViewMotion[]): object { public motionListToDocDef(
motions: ViewMotion[],
lnMode?: LineNumberingMode,
crMode?: ChangeRecoMode,
contentToExport?: string[],
infoToExport?: string[]
): 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) {
const motionDocDef: any = this.motionPdfService.motionToDocDef(motions[motionIndex]); const motionDocDef: any = this.motionPdfService.motionToDocDef(
motions[motionIndex],
lnMode,
crMode,
contentToExport,
infoToExport
);
// 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}`;

View File

@ -50,10 +50,20 @@ export class MotionPdfExportService {
/** /**
* Exports multiple motions to a collection of PDFs * Exports multiple motions to a collection of PDFs
* *
* @param motions * @param motions the motions to export
* @param lnMode lineNumbering Mode
* @param crMode Change Recommendation Mode
* @param contentToExport Determine to determine with text and/or reason
* @param infoToExport Determine the meta info to export
*/ */
public exportMotionCatalog(motions: ViewMotion[]): void { public exportMotionCatalog(
const doc = this.pdfCatalogService.motionListToDocDef(motions); motions: ViewMotion[],
lnMode?: LineNumberingMode,
crMode?: ChangeRecoMode,
contentToExport?: string[],
infoToExport?: string[]
): void {
const doc = this.pdfCatalogService.motionListToDocDef(motions, lnMode, crMode, contentToExport, infoToExport);
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

View File

@ -47,9 +47,19 @@ export class MotionPdfService {
* @param motion the motion to convert to pdf * @param motion the motion to convert to pdf
* @param lnMode determine the used line mode * @param lnMode determine the used line mode
* @param crMode determine the used change Recommendation mode * @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.
* @returns doc def for the motion * @returns doc def for the motion
*/ */
public motionToDocDef(motion: ViewMotion, lnMode?: LineNumberingMode, crMode?: ChangeRecoMode): object { public motionToDocDef(
motion: ViewMotion,
lnMode?: LineNumberingMode,
crMode?: ChangeRecoMode,
contentToExport?: string[],
infoToExport?: string[]
): object {
let motionPdfContent = [];
// determine the default lnMode if not explicitly given // determine the default lnMode if not explicitly given
if (!lnMode) { if (!lnMode) {
lnMode = this.configService.instant('motions_default_line_numbering'); lnMode = this.configService.instant('motions_default_line_numbering');
@ -62,12 +72,26 @@ export class MotionPdfService {
const title = this.createTitle(motion); const title = this.createTitle(motion);
const subtitle = this.createSubtitle(motion); const subtitle = this.createSubtitle(motion);
const metaInfo = this.createMetaInfoTable(motion, crMode);
const preamble = this.createPreamble(motion);
const text = this.createText(motion, lnMode, crMode);
const reason = this.createReason(motion, lnMode);
const motionPdfContent = [title, subtitle, metaInfo, preamble, text, reason]; motionPdfContent = [title, subtitle];
if ((infoToExport && infoToExport.length > 0) || !infoToExport) {
const metaInfo = this.createMetaInfoTable(motion, crMode, infoToExport);
motionPdfContent.push(metaInfo);
}
if (!contentToExport || contentToExport.includes('text')) {
const preamble = this.createPreamble(motion);
motionPdfContent.push(preamble);
const text = this.createText(motion, lnMode, crMode);
motionPdfContent.push(text);
}
if (!contentToExport || contentToExport.includes('reason')) {
const reason = this.createReason(motion, lnMode);
motionPdfContent.push(reason);
}
return motionPdfContent; return motionPdfContent;
} }
@ -119,39 +143,43 @@ export class MotionPdfService {
* @param motion the target motion * @param motion the target motion
* @returns doc def for the meta infos * @returns doc def for the meta infos
*/ */
private createMetaInfoTable(motion: ViewMotion, crMode: ChangeRecoMode): object { private createMetaInfoTable(motion: ViewMotion, crMode: ChangeRecoMode, infoToExport?: string[]): object {
const metaTableBody = []; const metaTableBody = [];
// submitters // submitters
const submitters = motion.submitters if (!infoToExport || infoToExport.includes('submitters')) {
.map(submitter => { const submitters = motion.submitters
return submitter.full_name; .map(submitter => {
}) return submitter.full_name;
.join(', '); })
.join(', ');
metaTableBody.push([ metaTableBody.push([
{ {
text: `${this.translate.instant('Submitters')}:`, text: `${this.translate.instant('Submitters')}:`,
style: 'boldText' style: 'boldText'
}, },
{ {
text: submitters text: submitters
} }
]); ]);
}
// state // state
metaTableBody.push([ if (!infoToExport || infoToExport.includes('state')) {
{ metaTableBody.push([
text: `${this.translate.instant('State')}:`, {
style: 'boldText' text: `${this.translate.instant('State')}:`,
}, style: 'boldText'
{ },
text: this.motionRepo.getExtendedStateLabel(motion) {
} text: this.motionRepo.getExtendedStateLabel(motion)
]); }
]);
}
// recommendation // recommendation
if (motion.recommendation) { if (motion.recommendation && (!infoToExport || infoToExport.includes('recommendation'))) {
metaTableBody.push([ metaTableBody.push([
{ {
text: `${this.translate.instant('Recommendation')}:`, text: `${this.translate.instant('Recommendation')}:`,
@ -164,7 +192,7 @@ export class MotionPdfService {
} }
// category // category
if (motion.category) { if (motion.category && (!infoToExport || infoToExport.includes('category'))) {
metaTableBody.push([ metaTableBody.push([
{ {
text: `${this.translate.instant('Category')}:`, text: `${this.translate.instant('Category')}:`,
@ -177,7 +205,7 @@ export class MotionPdfService {
} }
// motion block // motion block
if (motion.origin) { if (motion.motion_block && (!infoToExport || infoToExport.includes('block'))) {
metaTableBody.push([ metaTableBody.push([
{ {
text: `${this.translate.instant('Motion block')}:`, text: `${this.translate.instant('Motion block')}:`,
@ -190,11 +218,11 @@ export class MotionPdfService {
} }
// origin // origin
if (motion.origin) { if (motion.origin && (!infoToExport || infoToExport.includes('origin'))) {
metaTableBody.push([ metaTableBody.push([
{ {
text: `${this.translate.instant('Origin')}:`, text: `${this.translate.instant('Origin')}:`,
style: ['boldText', 'greyBackground'] style: 'boldText'
}, },
{ {
text: motion.origin text: motion.origin
@ -259,28 +287,30 @@ export class MotionPdfService {
]); ]);
} }
return { if (metaTableBody.length > 0) {
table: { return {
widths: ['35%', '65%'], table: {
body: metaTableBody widths: ['35%', '65%'],
}, body: metaTableBody
margin: [0, 0, 0, 20],
// That did not work too well in the past. Perhaps substitution by a pdfWorker the worker will be necessary
layout: {
fillColor: () => {
return '#dddddd';
}, },
hLineWidth: (i, node) => { margin: [0, 0, 0, 20],
return i === 0 || i === node.table.body.length ? 0 : 0.5; // That did not work too well in the past. Perhaps substitution by a pdfWorker the worker will be necessary
}, layout: {
vLineWidth: () => { fillColor: () => {
return 0; return '#dddddd';
}, },
hLineColor: () => { hLineWidth: (i, node) => {
return 'white'; return i === 0 || i === node.table.body.length ? 0 : 0.5;
},
vLineWidth: () => {
return 0;
},
hLineColor: () => {
return 'white';
}
} }
} };
}; }
} }
/** /**