Merge pull request #4189 from tsiegleauq/os3-motion-export-dialog
Add Motion Export dialog
This commit is contained in:
commit
56ff765708
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
@ -0,0 +1,3 @@
|
|||||||
|
.toggle-group-head {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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> ...</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>
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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 {}
|
||||||
|
@ -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'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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}`;
|
||||||
|
@ -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
|
||||||
|
@ -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';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user