Merge pull request #4195 from MaximilianKrambach/userPdf
user pdf exports: participant lists, access data
This commit is contained in:
commit
e0177893aa
@ -429,6 +429,19 @@ export class PdfDocumentService {
|
||||
margin: [0, 10, 0, 0],
|
||||
bold: true
|
||||
},
|
||||
userDataHeading: {
|
||||
fontSize: 14,
|
||||
margin: [0, 10],
|
||||
bold: true
|
||||
},
|
||||
userDataTopic: {
|
||||
fontSize: 12,
|
||||
margin: [0, 5]
|
||||
},
|
||||
userDataValue: {
|
||||
fontSize: 12,
|
||||
margin: [15, 5]
|
||||
},
|
||||
tocEntry: {
|
||||
fontSize: 12,
|
||||
margin: [0, 0, 0, 0],
|
||||
@ -446,6 +459,15 @@ export class PdfDocumentService {
|
||||
},
|
||||
tocCategorySection: {
|
||||
margin: [0, 0, 0, 10]
|
||||
},
|
||||
userDataTitle: {
|
||||
fontSize: 26,
|
||||
margin: [0, 0, 0, 0],
|
||||
bold: true
|
||||
},
|
||||
tableHeader: {
|
||||
bold: true,
|
||||
fillColor: 'white'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -29,6 +29,11 @@
|
||||
<mat-icon>security</mat-icon>
|
||||
<span translate>Change password</span>
|
||||
</button>
|
||||
<!-- PDF -->
|
||||
<button mat-menu-item *ngIf="isAllowed('seePersonal')" (click)="onDownloadPdf()">
|
||||
<mat-icon>picture_as_pdf</mat-icon>
|
||||
<span translate>PDF</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</os-head-bar>
|
||||
|
||||
|
@ -6,14 +6,15 @@ import { Title } from '@angular/platform-browser';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { genders } from 'app/shared/models/users/user';
|
||||
import { ViewUser } from '../../models/view-user';
|
||||
import { UserRepositoryService } from '../../services/user-repository.service';
|
||||
import { Group } from '../../../../shared/models/users/group';
|
||||
import { DataStoreService } from '../../../../core/services/data-store.service';
|
||||
import { OperatorService } from '../../../../core/services/operator.service';
|
||||
import { BaseViewComponent } from '../../../base/base-view';
|
||||
import { DataStoreService } from '../../../../core/services/data-store.service';
|
||||
import { genders } from 'app/shared/models/users/user';
|
||||
import { Group } from '../../../../shared/models/users/group';
|
||||
import { OperatorService } from '../../../../core/services/operator.service';
|
||||
import { PromptService } from '../../../../core/services/prompt.service';
|
||||
import { UserPdfExportService } from '../../services/user-pdf-export.service';
|
||||
import { UserRepositoryService } from '../../services/user-repository.service';
|
||||
import { ViewUser } from '../../models/view-user';
|
||||
|
||||
/**
|
||||
* Users detail component for both new and existing users
|
||||
@ -82,6 +83,7 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
* @param DS DataStoreService
|
||||
* @param operator OperatorService
|
||||
* @param promptService PromptService
|
||||
* @param pdfService UserPdfExportService used for export to pdf
|
||||
*/
|
||||
public constructor(
|
||||
title: Title,
|
||||
@ -93,7 +95,8 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
private repo: UserRepositoryService,
|
||||
private DS: DataStoreService,
|
||||
private operator: OperatorService,
|
||||
private promptService: PromptService
|
||||
private promptService: PromptService,
|
||||
private pdfService: UserPdfExportService
|
||||
) {
|
||||
super(title, translate, matSnackBar);
|
||||
|
||||
@ -359,4 +362,11 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the pdf download for this user
|
||||
*/
|
||||
public onDownloadPdf(): void {
|
||||
this.pdfService.exportSingleUserAccessPDF(this.user);
|
||||
}
|
||||
}
|
||||
|
@ -97,12 +97,16 @@
|
||||
<span translate>Groups</span>
|
||||
</button>
|
||||
|
||||
<div *ngIf="presenceViewConfigured">
|
||||
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="presence">
|
||||
<mat-icon>transfer_within_a_station</mat-icon>
|
||||
<span translate>Presence</span>
|
||||
</button>
|
||||
</div>
|
||||
<button mat-menu-item (click)="pdfExportUserList()">
|
||||
<mat-icon>picture_as_pdf</mat-icon>
|
||||
<span translate>List of participants (PDF)</span>
|
||||
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="onDownloadAccessPdf()">
|
||||
<mat-icon>picture_as_pdf</mat-icon>
|
||||
<span translate>Access data (PDF)</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="csvExportUserList()">
|
||||
<mat-icon>archive</mat-icon>
|
||||
@ -119,10 +123,12 @@
|
||||
<mat-icon>done_all</mat-icon>
|
||||
<span translate>Select all</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="deselectAll()">
|
||||
<mat-icon>clear</mat-icon>
|
||||
<span translate>Deselect all</span>
|
||||
</button>
|
||||
|
||||
<div *osPerms="'users.can_manage'">
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-menu-item (click)="setGroupSelected()">
|
||||
@ -130,35 +136,52 @@
|
||||
<span translate>Add/remove groups ...</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="setActiveSelected()">
|
||||
<mat-icon>block</mat-icon>
|
||||
<span translate>Enable/disable account ...</span>
|
||||
<div *ngIf="presenceViewConfigured">
|
||||
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="presence">
|
||||
<mat-icon>transfer_within_a_station</mat-icon>
|
||||
<span translate>Presence</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="import">
|
||||
<mat-icon>save_alt</mat-icon>
|
||||
<span translate>Import</span><span> ...</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="setPresentSelected()">
|
||||
<mat-icon>check_box</mat-icon>
|
||||
<span translate>Set presence ...</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="setCommitteeSelected()">
|
||||
<mat-icon>account_balance</mat-icon>
|
||||
<span translate>Set committee ...</span>
|
||||
</button>
|
||||
<div *osPerms="'users.can_manage'">
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-menu-item (click)="setActiveSelected()">
|
||||
<mat-icon>block</mat-icon>
|
||||
<span translate>Enable/disable account ...</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="sendInvitationEmailSelected()">
|
||||
<mat-icon>mail</mat-icon>
|
||||
<span translate>Send invitation email</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="resetPasswordsSelected()">
|
||||
<mat-icon>vpn_key</mat-icon>
|
||||
<span translate>Generate new passwords</span>
|
||||
</button>
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-menu-item class="red-warning-text" (click)="deleteSelected()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span translate>Delete</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="setPresentSelected()">
|
||||
<mat-icon>check_box</mat-icon>
|
||||
<span translate>Set presence ...</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="setCommitteeSelected()">
|
||||
<mat-icon>account_balance</mat-icon>
|
||||
<span translate>Set committee ...</span>
|
||||
</button>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<button mat-menu-item (click)="sendInvitationEmailSelected()">
|
||||
<mat-icon>mail</mat-icon>
|
||||
<span translate>Send invitation email</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="resetPasswordsSelected()">
|
||||
<mat-icon>vpn_key</mat-icon>
|
||||
<span translate>Generate new passwords</span>
|
||||
</button>
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-menu-item class="red-warning-text" (click)="deleteSelected()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span translate>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
@ -4,18 +4,19 @@ import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { CsvExportService } from '../../../../core/services/csv-export.service';
|
||||
import { ChoiceService } from '../../../../core/services/choice.service';
|
||||
import { ConfigService } from 'app/core/services/config.service';
|
||||
import { ListViewBaseComponent } from '../../../base/list-view-base';
|
||||
import { CsvExportService } from '../../../../core/services/csv-export.service';
|
||||
import { GroupRepositoryService } from '../../services/group-repository.service';
|
||||
import { ListViewBaseComponent } from '../../../base/list-view-base';
|
||||
import { PromptService } from '../../../../core/services/prompt.service';
|
||||
import { UserRepositoryService } from '../../services/user-repository.service';
|
||||
import { ViewUser } from '../../models/view-user';
|
||||
import { UserFilterListService } from '../../services/user-filter-list.service';
|
||||
import { UserRepositoryService } from '../../services/user-repository.service';
|
||||
import { UserPdfExportService } from '../../services/user-pdf-export.service';
|
||||
import { UserSortListService } from '../../services/user-sort-list.service';
|
||||
import { ViewportService } from '../../../../core/services/viewport.service';
|
||||
import { OperatorService } from '../../../../core/services/operator.service';
|
||||
import { ViewUser } from '../../models/view-user';
|
||||
|
||||
/**
|
||||
* Component for the user list view.
|
||||
@ -51,7 +52,6 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
||||
}
|
||||
|
||||
/**
|
||||
* /**
|
||||
* The usual constructor for components
|
||||
* @param titleService Serivce for setting the title
|
||||
* @param translate Service for translation handling
|
||||
@ -68,6 +68,7 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
||||
* @param filterService
|
||||
* @param sortService
|
||||
* @param config ConfigService
|
||||
* @param userPdf Service for downloading pdf
|
||||
*/
|
||||
public constructor(
|
||||
titleService: Title,
|
||||
@ -84,7 +85,8 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
||||
private promptService: PromptService,
|
||||
public filterService: UserFilterListService,
|
||||
public sortService: UserSortListService,
|
||||
config: ConfigService
|
||||
config: ConfigService,
|
||||
private userPdf: UserPdfExportService
|
||||
) {
|
||||
super(titleService, translate, matSnackBar);
|
||||
|
||||
@ -128,7 +130,8 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all users as CSV
|
||||
* Export all users currently matching the filter
|
||||
* as CSV (including personal information such as initial passwords)
|
||||
*/
|
||||
public csvExportUserList(): void {
|
||||
this.csvExport.export(
|
||||
@ -151,6 +154,22 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all users currently matching the filter as PDF
|
||||
* (access information, including personal information such as initial passwords)
|
||||
*/
|
||||
public onDownloadAccessPdf(): void {
|
||||
this.userPdf.exportMultipleUserAccessPDF(this.dataSource.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* triggers the download of a simple participant list (no details on user name and passwords)
|
||||
* with all users currently matching the filter
|
||||
*/
|
||||
public pdfExportUserList(): void {
|
||||
this.userPdf.exportUserList(this.dataSource.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk deletes users. Needs multiSelect mode to fill selectedRows
|
||||
*/
|
||||
|
@ -0,0 +1,17 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UserPdfExportService } from './user-pdf-export.service';
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
|
||||
describe('UserPdfExportService', () => {
|
||||
beforeEach(() =>
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule]
|
||||
})
|
||||
);
|
||||
|
||||
it('should be created', () => {
|
||||
const service: UserPdfExportService = TestBed.get(UserPdfExportService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,73 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { PdfDocumentService } from 'app/core/services/pdf-document.service';
|
||||
import { UserPdfService } from './user-pdf.service';
|
||||
import { ViewUser } from '../models/view-user';
|
||||
|
||||
/**
|
||||
* Export service to handle various kind of exporting necessities for participants.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserPdfExportService {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param translate TranslateService - handle translations
|
||||
* @param userPdfService UserPdfService - convert users to PDF
|
||||
* @param pdfDocumentService PdfDocumentService Actual pdfmake functions and global doc definitions
|
||||
*/
|
||||
public constructor(
|
||||
private translate: TranslateService,
|
||||
private userPdfService: UserPdfService,
|
||||
private pdfDocumentService: PdfDocumentService
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Exports a single user with access information to PDF
|
||||
*
|
||||
* @param user The user to export
|
||||
*/
|
||||
public exportSingleUserAccessPDF(user: ViewUser): void {
|
||||
const doc = this.userPdfService.userAccessToDocDef(user);
|
||||
const filename = `${this.translate.instant('User')} ${user.short_name}`;
|
||||
const metadata = {
|
||||
title: filename
|
||||
};
|
||||
this.pdfDocumentService.download(doc, filename, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports multiple users with access information to a collection of PDFs
|
||||
*
|
||||
* @param Users
|
||||
*/
|
||||
public exportMultipleUserAccessPDF(users: ViewUser[]): void {
|
||||
const doc: object[] = [];
|
||||
users.forEach(user => {
|
||||
doc.push(this.userPdfService.userAccessToDocDef(user));
|
||||
doc.push({ text: '', pageBreak: 'after' });
|
||||
});
|
||||
const filename = this.translate.instant('User');
|
||||
const metadata = {
|
||||
title: filename
|
||||
};
|
||||
this.pdfDocumentService.download(doc, filename, metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a participant list
|
||||
* @param users: The users to appear on that list
|
||||
*
|
||||
*/
|
||||
public exportUserList(users: ViewUser[]): void {
|
||||
const filename = this.translate.instant('List of participants');
|
||||
const metadata = {
|
||||
title: filename
|
||||
};
|
||||
this.pdfDocumentService.download(this.userPdfService.createUserListDocDef(users), filename, metadata);
|
||||
}
|
||||
}
|
17
client/src/app/site/users/services/user-pdf.service.spec.ts
Normal file
17
client/src/app/site/users/services/user-pdf.service.spec.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UserPdfService } from './user-pdf.service';
|
||||
import { E2EImportsModule } from 'e2e-imports.module';
|
||||
|
||||
describe('UserPdfService', () => {
|
||||
beforeEach(() =>
|
||||
TestBed.configureTestingModule({
|
||||
imports: [E2EImportsModule]
|
||||
})
|
||||
);
|
||||
|
||||
it('should be created', () => {
|
||||
const service: UserPdfService = TestBed.get(UserPdfService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
291
client/src/app/site/users/services/user-pdf.service.ts
Normal file
291
client/src/app/site/users/services/user-pdf.service.ts
Normal file
@ -0,0 +1,291 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { ConfigService } from 'app/core/services/config.service';
|
||||
import { ViewUser } from '../models/view-user';
|
||||
|
||||
/**
|
||||
* Creates a pdf for a user, containing greetings and initial login information
|
||||
* Provides the public methods `userAccessToDocDef(user: ViewUser)` and
|
||||
* `createUserListDocDef(users:ViewUser[])` which should be convenient to use.
|
||||
* @example
|
||||
* ```ts
|
||||
* const pdfMakeCompatibleDocDef = this.UserPdfService.userAccessToDocDef(User);
|
||||
* const pdfMakeCompatibleDocDef = this.UserPdfService.createUserListDocDef(Users);
|
||||
* ```
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserPdfService {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param translate handle translations
|
||||
* @param configService Read config variables
|
||||
*/
|
||||
public constructor(private translate: TranslateService, private configService: ConfigService) {}
|
||||
|
||||
/**
|
||||
* Converts a user to PdfMake doc definition, containing access information
|
||||
* for login and wlan access, if applicable
|
||||
*
|
||||
* @returns doc def for the user
|
||||
*/
|
||||
public userAccessToDocDef(user: ViewUser): object {
|
||||
const userHeadline = [
|
||||
{
|
||||
text: user.short_name,
|
||||
style: 'userDataTitle'
|
||||
}
|
||||
];
|
||||
if (user.structure_level) {
|
||||
userHeadline.push({
|
||||
text: user.structure_level,
|
||||
style: 'userDataHeading'
|
||||
});
|
||||
}
|
||||
return [userHeadline, this.createAccessDataContent(user), this.createWelcomeText()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the document definitions for a participant list with the given users, sorted as in the input.
|
||||
*
|
||||
* @param users An array of users
|
||||
* @returns pdfMake definitions for a table including name, structure level and groups for each user
|
||||
*/
|
||||
public createUserListDocDef(users: ViewUser[]): object {
|
||||
const title = {
|
||||
text: this.translate.instant('List of participants'),
|
||||
style: 'title'
|
||||
};
|
||||
return [title, this.createUserList(users)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the creation of access data for the given user
|
||||
*
|
||||
* @param user
|
||||
* @returns
|
||||
*/
|
||||
private createAccessDataContent(user: ViewUser): object {
|
||||
return {
|
||||
columns: [this.createWifiAccessContent(), this.createUserAccessContent(user)],
|
||||
margin: [0, 20]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the wifi access data, including qr code, for the configured event wlan parameters
|
||||
*
|
||||
* @returns pdfMake definitions
|
||||
*/
|
||||
private createWifiAccessContent(): object {
|
||||
const wifiColumn: object[] = [
|
||||
{
|
||||
text: this.translate.instant('WLAN access data'),
|
||||
style: 'userDataHeading'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('WLAN name (SSID)') + ':',
|
||||
style: 'userDataTopic'
|
||||
},
|
||||
{
|
||||
text: this.configService.instant<string>('users_pdf_wlan_ssid') || '-',
|
||||
style: 'userDataValue'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('WLAN password') + ':',
|
||||
style: 'userDataTopic'
|
||||
},
|
||||
{
|
||||
text: this.configService.instant<string>('users_pdf_wlan_password') || '-',
|
||||
style: 'userDataValue'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('WLAN encryption') + ':',
|
||||
style: 'userDataTopic'
|
||||
},
|
||||
{
|
||||
text: this.configService.instant<string>('users_pdf_wlan_encryption') || '-',
|
||||
style: 'userDataValue'
|
||||
},
|
||||
{
|
||||
text: '\n'
|
||||
}
|
||||
];
|
||||
if (
|
||||
this.configService.instant<string>('users_pdf_wlan_ssid') &&
|
||||
this.configService.instant<string>('users_pdf_wlan_encryption')
|
||||
) {
|
||||
const wifiQrCode =
|
||||
'WIFI:S:' +
|
||||
this.configService.instant<string>('users_pdf_wlan_ssid') +
|
||||
';T:' +
|
||||
this.configService.instant<string>('users_pdf_wlan_encryption') +
|
||||
';P:' +
|
||||
this.configService.instant<string>('users_pdf_wlan_password') +
|
||||
';;';
|
||||
wifiColumn.push(
|
||||
{
|
||||
qr: wifiQrCode,
|
||||
fit: 120,
|
||||
margin: [0, 0, 0, 8]
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Scan this QR code to connect to WLAN.'),
|
||||
style: 'small'
|
||||
}
|
||||
);
|
||||
}
|
||||
return wifiColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates access information (login name, initial password) for the given user,
|
||||
* additionally encoded in a qr code
|
||||
*
|
||||
* @param user
|
||||
* @returns pdfMake definitions
|
||||
*/
|
||||
private createUserAccessContent(user: ViewUser): object {
|
||||
const columnOpenSlides: object[] = [
|
||||
{
|
||||
text: this.translate.instant('OpenSlides access data'),
|
||||
style: 'userDataHeading'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Username') + ':',
|
||||
style: 'userDataTopic'
|
||||
},
|
||||
{
|
||||
text: user.username,
|
||||
style: 'userDataValue'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Initial password') + ':',
|
||||
style: 'userDataTopic'
|
||||
},
|
||||
{
|
||||
text: user.default_password,
|
||||
style: 'userDataValue'
|
||||
},
|
||||
{
|
||||
text: 'URL:',
|
||||
style: 'userDataTopic'
|
||||
},
|
||||
{
|
||||
text: this.configService.instant<string>('users_pdf_url') || '-',
|
||||
link: this.configService.instant<string>('users_pdf_url'),
|
||||
style: 'userDataValue'
|
||||
},
|
||||
{
|
||||
text: '\n'
|
||||
}
|
||||
];
|
||||
// url qr code
|
||||
if (this.configService.instant<string>('users_pdf_url')) {
|
||||
columnOpenSlides.push(
|
||||
{
|
||||
qr: this.configService.instant<string>('users_pdf_url'),
|
||||
fit: 120,
|
||||
margin: [0, 0, 0, 8]
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Scan this QR code to open URL.'),
|
||||
style: 'small'
|
||||
}
|
||||
);
|
||||
}
|
||||
return columnOpenSlides;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a welcone text according to the events' configuration
|
||||
*
|
||||
* @returns pdfMake definitions
|
||||
*/
|
||||
private createWelcomeText(): object {
|
||||
return [
|
||||
{
|
||||
text: this.translate.instant(this.configService.instant<string>('users_pdf_welcometitle')),
|
||||
style: 'userDataHeading'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant(this.configService.instant<string>('users_pdf_welcometext')),
|
||||
style: 'userDataTopic'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the creation of the participant lists' table structure
|
||||
*
|
||||
* @param users: passed through to getListUsers
|
||||
* @returns a pdfMake table definition ready to be put into a page
|
||||
*/
|
||||
private createUserList(users: ViewUser[]): object {
|
||||
const userTableBody: object[] = [
|
||||
[
|
||||
{
|
||||
text: '#',
|
||||
style: 'tableHeader'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Name'),
|
||||
style: 'tableHeader'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Structure level'),
|
||||
style: 'tableHeader'
|
||||
},
|
||||
{
|
||||
text: this.translate.instant('Groups'),
|
||||
style: 'tableHeader'
|
||||
}
|
||||
]
|
||||
];
|
||||
return {
|
||||
table: {
|
||||
widths: ['auto', '*', 'auto', 'auto'],
|
||||
headerRows: 1,
|
||||
body: userTableBody.concat(this.getListUsers(users))
|
||||
},
|
||||
layout: {
|
||||
hLineWidth: rowIndex => {
|
||||
return rowIndex === 1;
|
||||
},
|
||||
vLineWidth: () => {
|
||||
return 0;
|
||||
},
|
||||
fillColor: rowIndex => {
|
||||
return rowIndex % 2 === 0 ? '#EEEEEE' : null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the incoming users and generates pdfmake table lines for each of them
|
||||
*
|
||||
* @param users: The users to include, in order
|
||||
* @returns column definitions with odd and even entries styled differently,
|
||||
* short name, structure level and group name columns
|
||||
*/
|
||||
private getListUsers(users: ViewUser[]): object[] {
|
||||
const result = [];
|
||||
let counter = 1;
|
||||
users.forEach(user => {
|
||||
const groupList = user.groups.map(grp => this.translate.instant(grp.name));
|
||||
result.push([
|
||||
{ text: '' + counter },
|
||||
{ text: user.short_name },
|
||||
{ text: user.structure_level },
|
||||
{ text: groupList.join(', ') }
|
||||
]);
|
||||
counter += 1;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user