Merge pull request #5075 from jsangmeister/personal-comment-export

Added motion export option for personal note and fixed export error
This commit is contained in:
Sean 2019-10-21 11:54:17 +02:00 committed by GitHub
commit 9f25f2bc34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 199 additions and 154 deletions

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { LineNumberingMode } from 'app/site/motions/models/view-motion';
import { LineNumberingMode } from 'app/site/motions/motions.constants';
/**
* Shape of line number objects

View File

@ -35,7 +35,7 @@ function applyLayout(content: any): void {
if (Array.isArray(section)) {
applyLayout(section);
} else {
if (section.layout) {
if (section && section.layout) {
let layout: object;
switch (section.layout) {
case 'switchColorTableLayout': {

View File

@ -15,9 +15,10 @@ import {
MotionChangeRecommendationTitleInformation,
ViewMotionChangeRecommendation
} from 'app/site/motions/models/view-motion-change-recommendation';
import { ChangeRecoMode } from 'app/site/motions/motions.constants';
import { BaseRepository } from '../base-repository';
import { DiffService, LineRange, ModificationType } from '../../ui-services/diff.service';
import { ChangeRecoMode, ViewMotion } from '../../../site/motions/models/view-motion';
import { ViewMotion } from '../../../site/motions/models/view-motion';
import { ViewUnifiedChange } from '../../../shared/models/motions/view-unified-change';
/**

View File

@ -20,7 +20,7 @@ import { ViewUnifiedChange, ViewUnifiedChangeType } from 'app/shared/models/moti
import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
import { ViewCategory } from 'app/site/motions/models/view-category';
import { ChangeRecoMode, MotionTitleInformation, ViewMotion } from 'app/site/motions/models/view-motion';
import { MotionTitleInformation, ViewMotion } from 'app/site/motions/models/view-motion';
import { ViewMotionAmendedParagraph } from 'app/site/motions/models/view-motion-amended-paragraph';
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation';
@ -28,6 +28,7 @@ import { ViewState } from 'app/site/motions/models/view-state';
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { ViewSubmitter } from 'app/site/motions/models/view-submitter';
import { ViewWorkflow } from 'app/site/motions/models/view-workflow';
import { ChangeRecoMode } from 'app/site/motions/motions.constants';
import { ViewTag } from 'app/site/tags/models/view-tag';
import { ViewPersonalNote } from 'app/site/users/models/view-personal-note';
import { ViewUser } from 'app/site/users/models/view-user';

View File

@ -19,40 +19,6 @@ import { ViewState } from './view-state';
import { ViewSubmitter } from './view-submitter';
import { ViewWorkflow } from './view-workflow';
/**
* The line numbering mode for the motion detail view.
* The constants need to be in sync with the values saved in the config store.
*/
export enum LineNumberingMode {
None = 'none',
Inside = 'inline',
Outside = 'outside'
}
/**
* The change recommendation mode for the motion detail view.
*/
export enum ChangeRecoMode {
Original = 'original',
Changed = 'changed',
Diff = 'diff',
Final = 'agreed',
ModifiedFinal = 'modified_final_version'
}
export enum AmendmentType {
Amendment = 1,
Parent
}
export const verboseChangeRecoMode = {
original: 'Original version',
changed: 'Changed version',
diff: 'Diff version',
agreed: 'Final version',
modified_final_version: 'Final print template'
};
export interface MotionTitleInformation extends TitleInformationWithAgendaItem {
title: string;
identifier?: string;

View File

@ -5,8 +5,9 @@ import { E2EImportsModule } from 'e2e-imports.module';
import { Motion } from 'app/shared/models/motions/motion';
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
import { LineNumberingMode, ViewMotion } from 'app/site/motions/models/view-motion';
import { ViewMotion } from 'app/site/motions/models/view-motion';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation';
import { LineNumberingMode } from 'app/site/motions/motions.constants';
import { MotionDetailDiffComponent } from './motion-detail-diff.component';
import { MotionDetailOriginalChangeRecommendationsComponent } from '../motion-detail-original-change-recommendations/motion-detail-original-change-recommendations.component';

View File

@ -13,8 +13,9 @@ import { ViewUnifiedChange, ViewUnifiedChangeType } from 'app/shared/models/moti
import { mediumDialogSettings } from 'app/shared/utils/dialog-settings';
import { getRecommendationTypeName } from 'app/shared/utils/recommendation-type-names';
import { BaseViewComponent } from 'app/site/base/base-view';
import { LineNumberingMode, ViewMotion } from 'app/site/motions/models/view-motion';
import { ViewMotion } from 'app/site/motions/models/view-motion';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation';
import { LineNumberingMode } from 'app/site/motions/motions.constants';
import {
MotionChangeRecommendationDialogComponent,
MotionChangeRecommendationDialogComponentData

View File

@ -45,17 +45,19 @@ import { BaseViewComponent } from 'app/site/base/base-view';
import { CreateMotion } from 'app/site/motions/models/create-motion';
import { ViewCategory } from 'app/site/motions/models/view-category';
import { ViewCreateMotion } from 'app/site/motions/models/view-create-motion';
import {
ChangeRecoMode,
LineNumberingMode,
verboseChangeRecoMode,
ViewMotion
} from 'app/site/motions/models/view-motion';
import { ViewMotion } from 'app/site/motions/models/view-motion';
import { ViewMotionBlock } from 'app/site/motions/models/view-motion-block';
import { ViewMotionChangeRecommendation } from 'app/site/motions/models/view-motion-change-recommendation';
import { ViewStatuteParagraph } from 'app/site/motions/models/view-statute-paragraph';
import { ViewWorkflow } from 'app/site/motions/models/view-workflow';
import { MotionEditNotification, MotionEditNotificationType } from 'app/site/motions/motion-edit-notification';
import { MotionEditNotification } from 'app/site/motions/motion-edit-notification';
import {
ChangeRecoMode,
LineNumberingMode,
MotionEditNotificationType,
PERSONAL_NOTE_ID,
verboseChangeRecoMode
} from 'app/site/motions/motions.constants';
import { LocalPermissionsService } from 'app/site/motions/services/local-permissions.service';
import { MotionFilterListService } from 'app/site/motions/services/motion-filter-list.service';
import { MotionPdfExportService } from 'app/site/motions/services/motion-pdf-export.service';
@ -1345,7 +1347,7 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
this.pdfExport.exportSingleMotion(this.motion, {
lnMode: this.lnMode,
crMode: this.crMode,
comments: this.motion.commentSectionIds
comments: this.motion.commentSectionIds.concat([PERSONAL_NOTE_ID]) // export all comment fields as well as personal note
});
}

View File

@ -66,9 +66,12 @@
</mat-button-toggle-group>
</div>
<div *ngIf="commentsToExport.length">
<div>
<p class="toggle-group-head" translate>Comments</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="comments">
<mat-button-toggle [value]="PERSONAL_NOTE_ID">
<span translate>Personal note</span>
</mat-button-toggle>
<mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id">
<span>{{ comment.name }}</span>
</mat-button-toggle>

View File

@ -9,10 +9,15 @@ import { auditTime } from 'rxjs/operators';
import { StorageService } from 'app/core/core-services/storage.service';
import { MotionCommentSectionRepositoryService } from 'app/core/repositories/motions/motion-comment-section-repository.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { ChangeRecoMode, LineNumberingMode } from 'app/site/motions/models/view-motion';
import { ViewMotionCommentSection } from 'app/site/motions/models/view-motion-comment-section';
import { motionImportExportHeaderOrder, noMetaData } from 'app/site/motions/motion-import-export-order';
import { ExportFileFormat, MotionExportInfo } from 'app/site/motions/services/motion-export.service';
import {
ChangeRecoMode,
ExportFileFormat,
LineNumberingMode,
PERSONAL_NOTE_ID
} from 'app/site/motions/motions.constants';
import { motionImportExportHeaderOrder, noMetaData } from 'app/site/motions/motions.constants';
import { MotionExportInfo } from 'app/site/motions/services/motion-export.service';
/**
* Dialog component to determine exporting.
@ -24,6 +29,11 @@ import { ExportFileFormat, MotionExportInfo } from 'app/site/motions/services/mo
encapsulation: ViewEncapsulation.None
})
export class MotionExportDialogComponent implements OnInit {
/**
* import PERSONAL_NOTE_ID for use in template
*/
public PERSONAL_NOTE_ID = PERSONAL_NOTE_ID;
/**
* For using the enum constants from the template.
*/

View File

@ -1,27 +1,5 @@
/**
* Enum to define different types of notifications.
*/
export enum MotionEditNotificationType {
/**
* Type to declare editing a motion.
*/
TYPE_BEGIN_EDITING_MOTION = 'typeBeginEditingMotion',
import { MotionEditNotificationType } from './motions.constants';
/**
* Type if the edit-view is closing.
*/
TYPE_CLOSING_EDITING_MOTION = 'typeClosingEditingMotion',
/**
* Type if changes are saved.
*/
TYPE_SAVING_EDITING_MOTION = 'typeSavingEditingMotion',
/**
* Type to declare if another person is also editing the same motion.
*/
TYPE_ALSO_EDITING_MOTION = 'typeAlsoEditingMotion'
}
/**
* Class to specify the notifications for editing a motion.
*/

View File

@ -1,38 +0,0 @@
/**
* Defines the column order for csv/xlsx export/import of motions.
*/
export const motionImportExportHeaderOrder: string[] = [
'id',
'identifier',
'submitters',
'title',
'text',
'reason',
'category',
'tags',
'recommendation',
'state',
'motion_block',
'origin'
];
/**
* hints the metaData. This data will be excluded from the meta-data list in the export dialog.
* Order of this does not matter
*/
export const noMetaData: string[] = ['identifier', 'title', 'text', 'reason'];
/**
* Subset of {@link motionImportExportHeaderOrder} properties that are
* restricted to export only due to database or workflow limitations
*/
export const motionExportOnly: string[] = ['id', 'recommendation', 'state'];
/**
* reorders the exported properties according to motionImportExportHeaderOrder
*
* @param propertyList A list of motion properties to be ordered
*/
export function sortMotionPropertyList(propertyList: string[]): string[] {
return motionImportExportHeaderOrder.filter(property => propertyList.includes(property));
}

View File

@ -0,0 +1,132 @@
/**
* Central place for constants and enums for motions.
*/
/**
* Determines the possible file format of a motion export
*/
export enum ExportFileFormat {
PDF = 1,
CSV,
XLSX
}
/**
* Special id to reference the personal note in a comments list
*/
export const PERSONAL_NOTE_ID = -1;
/**
* Type declaring which strings are valid options for metainfos to be exported into a pdf
*/
export type InfoToExport =
| 'submitters'
| 'state'
| 'recommendation'
| 'category'
| 'motion_block'
| 'origin'
| 'tags'
| 'polls'
| 'speakers'
| 'id'
| 'allcomments';
/**
* The line numbering mode for the motion detail view.
* The constants need to be in sync with the values saved in the config store.
*/
export enum LineNumberingMode {
None = 'none',
Inside = 'inline',
Outside = 'outside'
}
/**
* The change recommendation mode for the motion detail view.
*/
export enum ChangeRecoMode {
Original = 'original',
Changed = 'changed',
Diff = 'diff',
Final = 'agreed',
ModifiedFinal = 'modified_final_version'
}
export enum AmendmentType {
Amendment = 1,
Parent
}
export const verboseChangeRecoMode = {
original: 'Original version',
changed: 'Changed version',
diff: 'Diff version',
agreed: 'Final version',
modified_final_version: 'Final print template'
};
/**
* Enum to define different types of notifications.
*/
export enum MotionEditNotificationType {
/**
* Type to declare editing a motion.
*/
TYPE_BEGIN_EDITING_MOTION = 'typeBeginEditingMotion',
/**
* Type if the edit-view is closing.
*/
TYPE_CLOSING_EDITING_MOTION = 'typeClosingEditingMotion',
/**
* Type if changes are saved.
*/
TYPE_SAVING_EDITING_MOTION = 'typeSavingEditingMotion',
/**
* Type to declare if another person is also editing the same motion.
*/
TYPE_ALSO_EDITING_MOTION = 'typeAlsoEditingMotion'
}
// import-export order specific constants
/**
* Defines the column order for csv/xlsx export/import of motions.
*/
export const motionImportExportHeaderOrder: string[] = [
'id',
'identifier',
'submitters',
'title',
'text',
'reason',
'category',
'tags',
'recommendation',
'state',
'motion_block',
'origin'
];
/**
* hints the metaData. This data will be excluded from the meta-data list in the export dialog.
* Order of this does not matter
*/
export const noMetaData: string[] = ['identifier', 'title', 'text', 'reason'];
/**
* Subset of {@link motionImportExportHeaderOrder} properties that are
* restricted to export only due to database or workflow limitations
*/
export const motionExportOnly: string[] = ['id', 'recommendation', 'state'];
/**
* reorders the exported properties according to motionImportExportHeaderOrder
*
* @param propertyList A list of motion properties to be ordered
*/
export function sortMotionPropertyList(propertyList: string[]): string[] {
return motionImportExportHeaderOrder.filter(property => propertyList.includes(property));
}

View File

@ -15,8 +15,8 @@ import { LinenumberingService } from 'app/core/ui-services/linenumbering.service
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
import { reconvertChars } from 'app/shared/utils/reconvert-chars';
import { stripHtmlTags } from 'app/shared/utils/strip-html-tags';
import { sortMotionPropertyList } from '../motion-import-export-order';
import { ChangeRecoMode, ViewMotion } from '../models/view-motion';
import { ChangeRecoMode, sortMotionPropertyList } from '../motions.constants';
import { ViewMotion } from '../models/view-motion';
/**
* Exports CSVs for motions. Collect all CSV types here to have them in one place.

View File

@ -3,18 +3,9 @@ import { Injectable } from '@angular/core';
import { PdfError } from 'app/core/pdf-services/pdf-document.service';
import { MotionCsvExportService } from './motion-csv-export.service';
import { MotionPdfExportService } from './motion-pdf-export.service';
import { InfoToExport } from './motion-pdf.service';
import { MotionXlsxExportService } from './motion-xlsx-export.service';
import { ChangeRecoMode, LineNumberingMode, ViewMotion } from '../models/view-motion';
/**
* Determine the possible file format
*/
export enum ExportFileFormat {
PDF = 1,
CSV,
XLSX
}
import { ChangeRecoMode, ExportFileFormat, InfoToExport, LineNumberingMode } from '../motions.constants';
import { ViewMotion } from '../models/view-motion';
/**
* Shape the structure of the dialog data

View File

@ -17,7 +17,8 @@ import {
OsFilterOptions
} from 'app/core/ui-services/base-filter-list.service';
import { ConfigService } from 'app/core/ui-services/config.service';
import { AmendmentType, ViewMotion } from '../models/view-motion';
import { AmendmentType } from '../motions.constants';
import { ViewMotion } from '../models/view-motion';
/**
* Filter description to easier parse dynamically occurring workflows

View File

@ -14,7 +14,7 @@ import { Tag } from 'app/shared/models/core/tag';
import { Category } from 'app/shared/models/motions/category';
import { MotionBlock } from 'app/shared/models/motions/motion-block';
import { CreateMotion } from '../models/create-motion';
import { motionExportOnly, motionImportExportHeaderOrder } from '../motion-import-export-order';
import { motionExportOnly, motionImportExportHeaderOrder } from '../motions.constants';
import { CsvMapping, ViewCsvCreateMotion } from '../models/view-csv-create-motion';
import { ViewMotion } from '../models/view-motion';

View File

@ -15,26 +15,11 @@ import { ViewUnifiedChange, ViewUnifiedChangeType } from 'app/shared/models/moti
import { getRecommendationTypeName } from 'app/shared/utils/recommendation-type-names';
import { MotionExportInfo } from './motion-export.service';
import { MotionPollService } from './motion-poll.service';
import { ChangeRecoMode, LineNumberingMode, ViewMotion } from '../models/view-motion';
import { ChangeRecoMode, InfoToExport, LineNumberingMode, PERSONAL_NOTE_ID } from '../motions.constants';
import { ViewMotion } from '../models/view-motion';
import { ViewMotionAmendedParagraph } from '../models/view-motion-amended-paragraph';
import { ViewMotionChangeRecommendation } from '../models/view-motion-change-recommendation';
/**
* Type declaring which strings are valid options for metainfos to be exported into a pdf
*/
export type InfoToExport =
| 'submitters'
| 'state'
| 'recommendation'
| 'category'
| 'motion_block'
| 'origin'
| 'tags'
| 'polls'
| 'speakers'
| 'id'
| 'allcomments';
/**
* Converts a motion to pdf. Can be used from the motion detail view or executed on a list of motions
* Provides the public method `motionToDocDef(motion: Motion)` which should be convenient to use.
@ -817,11 +802,20 @@ export class MotionPdfService {
private createComments(motion: ViewMotion, comments: number[]): object[] {
const result: object[] = [];
for (const comment of comments) {
const viewComment = this.commentRepo.getViewModel(comment);
const section = motion.getCommentForSection(viewComment);
if (section && section.comment) {
result.push({ text: viewComment.name, style: 'heading3', margin: [0, 25, 0, 10] });
result.push(this.htmlToPdfService.addPlainText(section.comment));
let name = '',
content = '';
if (comment === PERSONAL_NOTE_ID) {
name = this.translate.instant('Personal note');
content = motion && motion.personalNote && motion.personalNote.note;
} else {
const viewComment = this.commentRepo.getViewModel(comment);
const section = motion.getCommentForSection(viewComment);
name = viewComment.name;
content = section && section.comment;
}
if (name && content) {
result.push({ text: name, style: 'heading3', margin: [0, 25, 0, 10] });
result.push(this.htmlToPdfService.addPlainText(content));
}
}
return result;

View File

@ -8,8 +8,8 @@ import { MotionRepositoryService } from 'app/core/repositories/motions/motion-re
import { CellFillingDefinition, XlsxExportServiceService } from 'app/core/ui-services/xlsx-export-service.service';
import { reconvertChars } from 'app/shared/utils/reconvert-chars';
import { stripHtmlTags } from 'app/shared/utils/strip-html-tags';
import { sortMotionPropertyList } from '../motion-import-export-order';
import { InfoToExport } from './motion-pdf.service';
import { sortMotionPropertyList } from '../motions.constants';
import { InfoToExport } from '../motions.constants';
import { ViewMotion } from '../models/view-motion';
/**

View File

@ -1,4 +1,5 @@
import { ChangeRecoMode, LineNumberingMode, MotionTitleInformation } from 'app/site/motions/models/view-motion';
import { MotionTitleInformation } from 'app/site/motions/models/view-motion';
import { ChangeRecoMode, LineNumberingMode } from 'app/site/motions/motions.constants';
import { ReferencedMotions } from '../base/base-motion-slide';
/**

View File

@ -8,7 +8,8 @@ import { MotionRepositoryService } from 'app/core/repositories/motions/motion-re
import { DiffLinesInParagraph, DiffService, LineRange } from 'app/core/ui-services/diff.service';
import { LinenumberingService } from 'app/core/ui-services/linenumbering.service';
import { ViewUnifiedChange, ViewUnifiedChangeType } from 'app/shared/models/motions/view-unified-change';
import { ChangeRecoMode, LineNumberingMode, MotionTitleInformation } from 'app/site/motions/models/view-motion';
import { MotionTitleInformation } from 'app/site/motions/models/view-motion';
import { ChangeRecoMode, LineNumberingMode } from 'app/site/motions/motions.constants';
import { IBaseScaleScrollSlideComponent } from 'app/slides/base-scale-scroll-slide-component';
import { BaseMotionSlideComponent } from '../base/base-motion-slide';
import { MotionSlideData, MotionSlideDataAmendment } from './motion-slide-data';