import { Component, OnChanges, OnInit } from '@angular/core'; import { AdminUsersService } from '@core/services/admin-users.service'; import { ApplicantService } from '@core/services/auth-user/applicant.service'; import { SpinnerService } from '@core/services/spinner.service'; import { APIAdminClient } from '@core/typings/api/admin-client.typing'; import { ApplicantAdminUser } from '@core/typings/applicant.typing'; import { AdminUserPermissions } from '@core/typings/user.typing'; import { ApplicantUserModalComponent } from '@features/platform-admin/applicants/applicant-user-modal/applicant-user-modal.component'; import { UserService } from '@features/users/user.service'; import { DebounceFactory, PaginationOptions, TableDataFactory, TopLevelFilter, TopLevelFilterOption } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { LogService } from '@yourcause/common/logging'; import { ModalFactory } from '@yourcause/common/modals'; import { NotifierService } from '@yourcause/common/notifier'; import { AdminClientService } from '../clients/admin-client.service'; import { ApplicantEmailLinkModalComponent } from './applicant-email-link-modal/applicant-email-link-modal.component'; @Component({ selector: 'gc-applicants', templateUrl: './applicants.component.html', styleUrls: ['./applicants.component.scss'] }) export class ApplicantsComponent implements OnInit, OnChanges { tableListFilters: TopLevelFilter[] = []; tableListFactory: TableDataFactory; clientOptions: TopLevelFilterOption[] = []; userId = this.userService.currentUser.id; allowedClients: APIAdminClient.Client[]; clients = this.adminClientService.clients || []; adminPermissions = this.userService.adminPermissions; canEditApplicants = this.adminPermissions.includes(AdminUserPermissions.EditApplicants); constructor ( private logger: LogService, private adminClientService: AdminClientService, private applicantService: ApplicantService, private adminUserService: AdminUsersService, private userService: UserService, private modalFactory: ModalFactory, private notifier: NotifierService, private spinnerService: SpinnerService, private i18n: I18nService ) { } async ngOnInit () { const adminDetail = await this.adminUserService.getAdminDetail(this.userId); this.clientOptions = this.adminClientService.getClientOptionsForAdmin(adminDetail); this.tableListFilters = [ new TopLevelFilter( 'checkboxDropdown', 'clientId', [], this.i18n.translate( 'ADMIN:textAllClientsSelected', {}, 'All clients selected' ), { selectOptions: this.clientOptions, filterObjectName: this.i18n.translate( 'common:labelClient', {}, 'Client' ).toLowerCase(), filterObjectNamePlural: this.i18n.translate( 'common:textClients', {}, 'Clients' ).toLowerCase() } )]; const filter = new TopLevelFilter( 'text', 'fullName', '', this.i18n.translate( 'ADMIN:textSearchForApplicant', {}, 'Search for an applicant' ), undefined, undefined, [{ column: 'fullName', filterType: 'cn' }, { column: 'email', filterType: 'cn' }] ); this.tableListFilters.push(filter); this.tableListFactory = DebounceFactory.createSimple( async (options: PaginationOptions) => { const clientFilterIndex = options.filterColumns.findIndex((f) => { return f.columnName === 'clientId'; }); let clientIds: number[] = []; if (clientFilterIndex > -1) { const clientFilter = options.filterColumns[clientFilterIndex]; clientIds = clientFilter.filters.map((f) => { return f.filterValue as number; }); options = { ...options, filterColumns: [ ...options.filterColumns.slice(0, clientFilterIndex), ...options.filterColumns.slice(clientFilterIndex + 1) ] }; } const result = await this.applicantService.adminApplicantsPaginated( options, clientIds ); return { success: true, data: { recordCount: result.recordCount, records: result.records } }; } ); } async confirmEmail (user: ApplicantAdminUser) { try { const result = await this.applicantService.confirmEmailAddress(user.id); if (!result) { this.notifier.error(this.i18n.translate( 'ADMIN:errorEmailAddressNotConfirmed', {}, 'Email address could not be confirmed' )); return; } this.notifier.success(this.i18n.translate( 'GLOBAL:notificationEmailConfirmed', {}, 'Email confirmed' )); this.tableListFactory.reset.emit(); } catch (error) { this.notifier.error(this.i18n.translate( 'ADMIN:errorConfirmingEmailAddress', {}, 'There was an error confirming the email address' )); } } async editApplicant (user: ApplicantAdminUser) { const deps = { user }; const response = await this.modalFactory.open( ApplicantUserModalComponent, deps ); if (response) { this.spinnerService.startSpinner(); await this.handleSubmit(response); this.spinnerService.stopSpinner(); } } async handleSubmit (user: ApplicantAdminUser) { try { await this.applicantService.updateApplicant(user); this.tableListFactory.reset.emit(); this.notifier.success(this.i18n.translate( 'ADMIN:notificationSuccesfulUserSubmission', {}, 'User submission was successful' )); } catch (error) { this.logger.error(error); this.notifier.error(this.i18n.translate( 'ADMIN:notificationErrorSendingUser', {}, 'There was an error sending the user information.' )); } } async generateEmailLink (user: ApplicantAdminUser) { const deps = { user, modalType: 'applicant' }; const response = await this.modalFactory.open( ApplicantEmailLinkModalComponent, deps ); if (response) { document.addEventListener('copy', (e: ClipboardEvent) => { e.clipboardData.setData('text/plain', (response)); e.preventDefault(); document.removeEventListener('copy', null); }); document.execCommand('copy'); this.notifier.success(this.i18n.translate( 'ADMIN:LinkCopied', {}, 'Link copied' )); } } ngOnChanges () { if (this.tableListFactory) { this.tableListFactory.reset.emit(); } } }