user pdf exports: participant lists, access data
This commit is contained in:
parent
00b15228f7
commit
6b0f129067
@ -429,6 +429,19 @@ export class PdfDocumentService {
|
|||||||
margin: [0, 10, 0, 0],
|
margin: [0, 10, 0, 0],
|
||||||
bold: true
|
bold: true
|
||||||
},
|
},
|
||||||
|
userDataHeading: {
|
||||||
|
fontSize: 14,
|
||||||
|
margin: [0, 10],
|
||||||
|
bold: true
|
||||||
|
},
|
||||||
|
userDataTopic: {
|
||||||
|
fontSize: 12,
|
||||||
|
margin: [0, 5]
|
||||||
|
},
|
||||||
|
userDataValue: {
|
||||||
|
fontSize: 12,
|
||||||
|
margin: [15, 5]
|
||||||
|
},
|
||||||
tocEntry: {
|
tocEntry: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
margin: [0, 0, 0, 0],
|
margin: [0, 0, 0, 0],
|
||||||
@ -446,6 +459,15 @@ export class PdfDocumentService {
|
|||||||
},
|
},
|
||||||
tocCategorySection: {
|
tocCategorySection: {
|
||||||
margin: [0, 0, 0, 10]
|
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>
|
<mat-icon>security</mat-icon>
|
||||||
<span translate>Change password</span>
|
<span translate>Change password</span>
|
||||||
</button>
|
</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>
|
</mat-menu>
|
||||||
</os-head-bar>
|
</os-head-bar>
|
||||||
|
|
||||||
|
@ -6,14 +6,15 @@ import { Title } from '@angular/platform-browser';
|
|||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
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 { 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 { 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
|
* Users detail component for both new and existing users
|
||||||
@ -82,6 +83,7 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
* @param DS DataStoreService
|
* @param DS DataStoreService
|
||||||
* @param operator OperatorService
|
* @param operator OperatorService
|
||||||
* @param promptService PromptService
|
* @param promptService PromptService
|
||||||
|
* @param pdfService UserPdfExportService used for export to pdf
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
title: Title,
|
title: Title,
|
||||||
@ -93,7 +95,8 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
private repo: UserRepositoryService,
|
private repo: UserRepositoryService,
|
||||||
private DS: DataStoreService,
|
private DS: DataStoreService,
|
||||||
private operator: OperatorService,
|
private operator: OperatorService,
|
||||||
private promptService: PromptService
|
private promptService: PromptService,
|
||||||
|
private pdfService: UserPdfExportService
|
||||||
) {
|
) {
|
||||||
super(title, translate, matSnackBar);
|
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>
|
<span translate>Groups</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div *ngIf="presenceViewConfigured">
|
<button mat-menu-item (click)="pdfExportUserList()">
|
||||||
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="presence">
|
<mat-icon>picture_as_pdf</mat-icon>
|
||||||
<mat-icon>transfer_within_a_station</mat-icon>
|
<span translate>List of participants (PDF)</span>
|
||||||
<span translate>Presence</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
|
<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()">
|
<button mat-menu-item (click)="csvExportUserList()">
|
||||||
<mat-icon>archive</mat-icon>
|
<mat-icon>archive</mat-icon>
|
||||||
@ -119,10 +123,12 @@
|
|||||||
<mat-icon>done_all</mat-icon>
|
<mat-icon>done_all</mat-icon>
|
||||||
<span translate>Select all</span>
|
<span translate>Select all</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item (click)="deselectAll()">
|
<button mat-menu-item (click)="deselectAll()">
|
||||||
<mat-icon>clear</mat-icon>
|
<mat-icon>clear</mat-icon>
|
||||||
<span translate>Deselect all</span>
|
<span translate>Deselect all</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div *osPerms="'users.can_manage'">
|
<div *osPerms="'users.can_manage'">
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button mat-menu-item (click)="setGroupSelected()">
|
<button mat-menu-item (click)="setGroupSelected()">
|
||||||
@ -130,35 +136,52 @@
|
|||||||
<span translate>Add/remove groups ...</span>
|
<span translate>Add/remove groups ...</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item (click)="setActiveSelected()">
|
<div *ngIf="presenceViewConfigured">
|
||||||
<mat-icon>block</mat-icon>
|
<button mat-menu-item *osPerms="'users.can_manage'" routerLink="presence">
|
||||||
<span translate>Enable/disable account ...</span>
|
<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>
|
||||||
|
|
||||||
<button mat-menu-item (click)="setPresentSelected()">
|
<div *osPerms="'users.can_manage'">
|
||||||
<mat-icon>check_box</mat-icon>
|
<mat-divider></mat-divider>
|
||||||
<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)="setActiveSelected()">
|
||||||
|
<mat-icon>block</mat-icon>
|
||||||
|
<span translate>Enable/disable account ...</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item (click)="sendInvitationEmailSelected()">
|
<button mat-menu-item (click)="setPresentSelected()">
|
||||||
<mat-icon>mail</mat-icon>
|
<mat-icon>check_box</mat-icon>
|
||||||
<span translate>Send invitation email</span>
|
<span translate>Set presence ...</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="resetPasswordsSelected()">
|
|
||||||
<mat-icon>vpn_key</mat-icon>
|
<button mat-menu-item (click)="setCommitteeSelected()">
|
||||||
<span translate>Generate new passwords</span>
|
<mat-icon>account_balance</mat-icon>
|
||||||
</button>
|
<span translate>Set committee ...</span>
|
||||||
<mat-divider></mat-divider>
|
</button>
|
||||||
<button mat-menu-item class="red-warning-text" (click)="deleteSelected()">
|
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-divider></mat-divider>
|
||||||
<span translate>Delete</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>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
@ -4,18 +4,19 @@ import { Router, ActivatedRoute } from '@angular/router';
|
|||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { CsvExportService } from '../../../../core/services/csv-export.service';
|
|
||||||
import { ChoiceService } from '../../../../core/services/choice.service';
|
import { ChoiceService } from '../../../../core/services/choice.service';
|
||||||
import { ConfigService } from 'app/core/services/config.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 { GroupRepositoryService } from '../../services/group-repository.service';
|
||||||
|
import { ListViewBaseComponent } from '../../../base/list-view-base';
|
||||||
import { PromptService } from '../../../../core/services/prompt.service';
|
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 { 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 { UserSortListService } from '../../services/user-sort-list.service';
|
||||||
import { ViewportService } from '../../../../core/services/viewport.service';
|
import { ViewportService } from '../../../../core/services/viewport.service';
|
||||||
import { OperatorService } from '../../../../core/services/operator.service';
|
import { OperatorService } from '../../../../core/services/operator.service';
|
||||||
|
import { ViewUser } from '../../models/view-user';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component for the user list view.
|
* Component for the user list view.
|
||||||
@ -51,7 +52,6 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /**
|
|
||||||
* The usual constructor for components
|
* The usual constructor for components
|
||||||
* @param titleService Serivce for setting the title
|
* @param titleService Serivce for setting the title
|
||||||
* @param translate Service for translation handling
|
* @param translate Service for translation handling
|
||||||
@ -68,6 +68,7 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
|||||||
* @param filterService
|
* @param filterService
|
||||||
* @param sortService
|
* @param sortService
|
||||||
* @param config ConfigService
|
* @param config ConfigService
|
||||||
|
* @param userPdf Service for downloading pdf
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
titleService: Title,
|
titleService: Title,
|
||||||
@ -84,7 +85,8 @@ export class UserListComponent extends ListViewBaseComponent<ViewUser> implement
|
|||||||
private promptService: PromptService,
|
private promptService: PromptService,
|
||||||
public filterService: UserFilterListService,
|
public filterService: UserFilterListService,
|
||||||
public sortService: UserSortListService,
|
public sortService: UserSortListService,
|
||||||
config: ConfigService
|
config: ConfigService,
|
||||||
|
private userPdf: UserPdfExportService
|
||||||
) {
|
) {
|
||||||
super(titleService, translate, matSnackBar);
|
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 {
|
public csvExportUserList(): void {
|
||||||
this.csvExport.export(
|
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
|
* 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