From 23fea51333b3cda34e844d2bbe0d3f76868a0a87 Mon Sep 17 00:00:00 2001 From: Sean Engelhardt Date: Fri, 25 Jan 2019 17:03:05 +0100 Subject: [PATCH] Add Motion Export dialog Removes the "Export As CSV" and "Export As PDF" options from MotionList view and adds an export dialog instead (just like OS 2.3) The exprt Dialog dynamically changes it's content according to the possible selections. The current implementation of the CSV exporter is not able to export anything but the original motion text. The exporter does consider this and disables this option for now. While the old exporter showed "state" and "recommendation" during CSV export, but was in fact not exporting state nor recommendation, the new exporter will disable these fields during CSV export. PDF should work as expected --- .../app/core/services/csv-export.service.ts | 2 +- .../motion-export-dialog.component.html | 68 +++++++ .../motion-export-dialog.component.scss | 3 + .../motion-export-dialog.component.spec.ts | 28 +++ .../motion-export-dialog.component.ts | 186 ++++++++++++++++++ .../motion-list/motion-list.component.html | 8 +- .../motion-list/motion-list.component.ts | 35 +++- client/src/app/site/motions/motions.module.ts | 7 +- .../services/motion-csv-export.service.ts | 25 +-- .../services/motion-pdf-catalog.service.ts | 18 +- .../services/motion-pdf-export.service.ts | 16 +- .../motions/services/motion-pdf.service.ts | 140 +++++++------ 12 files changed, 441 insertions(+), 95 deletions(-) create mode 100644 client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.html create mode 100644 client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.scss create mode 100644 client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.spec.ts create mode 100644 client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.ts diff --git a/client/src/app/core/services/csv-export.service.ts b/client/src/app/core/services/csv-export.service.ts index c7f6e85b8..c64807161 100644 --- a/client/src/app/core/services/csv-export.service.ts +++ b/client/src/app/core/services/csv-export.service.ts @@ -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 * translated and capitalized property name is used. */ -interface CsvColumnDefinitionProperty { +export interface CsvColumnDefinitionProperty { label?: string; property: keyof T; } diff --git a/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.html b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.html new file mode 100644 index 000000000..27234bc55 --- /dev/null +++ b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.html @@ -0,0 +1,68 @@ +

{{ 'Export motions' | translate }}

+ +
+ +
+
+

Format

+ + PDF + CSV + +
+ +
+

Line numbering

+ + None + Inline + Outside + +
+ +
+

Change recommendations

+ + + Original version + + Changed version + + Diff version + + Final version + +
+ +
+

Content

+ + Text + Reason + +
+ +
+

Meta information

+ + Submitters + State + Recommendation + Category + Origin + Motion block + Voting Result + +
+ +
+
+ + +
+ + +
+
diff --git a/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.scss b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.scss new file mode 100644 index 000000000..537803a76 --- /dev/null +++ b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.scss @@ -0,0 +1,3 @@ +.toggle-group-head { + margin-bottom: 0; +} diff --git a/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.spec.ts b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.spec.ts new file mode 100644 index 000000000..b4e06a46e --- /dev/null +++ b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.spec.ts @@ -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; + + 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(); + }); +}); diff --git a/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.ts b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.ts new file mode 100644 index 000000000..a3e2e1f43 --- /dev/null +++ b/client/src/app/site/motions/components/motion-export-dialog/motion-export-dialog.component.ts @@ -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, + 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(); + } +} diff --git a/client/src/app/site/motions/components/motion-list/motion-list.component.html b/client/src/app/site/motions/components/motion-list/motion-list.component.html index 3e418fcb1..329c1526e 100644 --- a/client/src/app/site/motions/components/motion-list/motion-list.component.html +++ b/client/src/app/site/motions/components/motion-list/motion-list.component.html @@ -174,13 +174,9 @@ local_offer Tags - -