import { Component, OnDestroy, OnInit } from '@angular/core'; import { SpinnerService } from '@core/services/spinner.service'; import { FooterState } from '@core/states/footer.state'; import { AdHocReportingAPI } from '@core/typings/api/ad-hoc-reporting.typing'; import { APConfigAPI } from '@core/typings/api/ap-config.typing'; import { AdHocReportingUI } from '@core/typings/ui/ad-hoc-reporting.typing'; import { AudienceService } from '@features/audience/audience.service'; import { Audience } from '@features/audience/audience.typing'; import { ClientSettingsService } from '@features/client-settings/client-settings.service'; import { SFTPService } from '@features/sftp/sftp.service'; import { ArrayHelpersService, PanelTypes, TableDataDownloadFormat, TypeaheadSelectOption, TypeSafeFormBuilder, TypeSafeFormGroup } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { ModalFactory } from '@yourcause/common/modals'; import { APConfigService } from '../ap-config.service'; import { ImportVendorModalComponent } from '../import-vender-modal/import-vendor-modal.component'; interface ApConfigFormGroup { audience: number; exportDestination: number; exportFileTypeId: TableDataDownloadFormat; } @Component({ selector: 'gc-ap-config-page', templateUrl: 'ap-config-page.component.html', styleUrls: ['./ap-config-page.component.scss'] }) export class APConfigPageComponent implements OnInit, OnDestroy { ready = false; formGroup: TypeSafeFormGroup; PanelTypes = PanelTypes; reportDetails = {} as AdHocReportingAPI.UserSavedReportDetail; mode = AdHocReportingUI.AdHocBuilderComponentMode.SCAFFOLD; clientName = this.clientSettingsService.clientBranding.name; apSettingsColumns: APConfigAPI.APSettingsColumn[]; columnsForAdHocComponent: AdHocReportingUI.ColumnImplementation[] = []; exportHeadersDescription = this.i18n.translate( 'CONFIG:textAPExportHeadersDescription', {}, 'Define the headers for Accounts Payable exports in Payment Processing' ); exportHeadersText = this.i18n.translate( 'common:textExportHeaders', {}, 'Export Headers' ); destinationSettingsText = this.i18n.translate( 'CONFIG:textDestinationSettings', {}, 'Destination Settings' ); secureStorageText = this.i18n.translate( 'common:textGrantsConnectSecureStorage', {}, 'GrantsConnect secure storage' ); noAudiencesText = this.i18n.translate( 'CONFIG:textNoAudiencesNoEmail', {}, 'No audience selected. No email will be sent' ); fileTypeOptions: TypeaheadSelectOption[] = [{ label: this.i18n.translate( 'common:textCSV', {}, 'CSV' ), value: TableDataDownloadFormat.CSV }, { label: this.i18n.translate( 'common:textExcel', {}, 'Excel' ), value: TableDataDownloadFormat.XLSX }]; exportDestinationOptions: TypeaheadSelectOption[]; audienceOptions: TypeaheadSelectOption[]; constructor ( private i18n: I18nService, private formBuilder: TypeSafeFormBuilder, private sFTPService: SFTPService, private audienceService: AudienceService, private arrayHelper: ArrayHelpersService, private footerState: FooterState, private clientSettingsService: ClientSettingsService, private modalFactory: ModalFactory, private apConfigService: APConfigService, private spinnerService: SpinnerService ) { this.footerState.set('footerState', footerState.FOOTER_STATES.ACTION); this.footerState.set('footerAction', () => this.saveAPConfig()); this.footerState.set('footerActionLabel', i18n.translate('common:btnSave')); } get hasAudienceOptions () { return this.audienceService.allAudiences.length > 0; } ngOnInit () { this.setDestinationOptions(); this.setAudienceOptions(); this.formGroup = this.formBuilder.group({ audience: this.apConfigService.apConfig?.audienceId ?? null, exportDestination: this.apConfigService.apConfig?.sftpDetailsId ?? 0, exportFileTypeId: this.apConfigService.apConfig?.exportFileTypeId ?? TableDataDownloadFormat.CSV }); this.setAPSettingsColumns(); this.ready = true; } setAPSettingsColumns () { if (this.apConfigService.apConfig) { this.apSettingsColumns = this.apConfigService.apConfig.accountsPayableSettingsColumns || null; this.columnsForAdHocComponent = this.apConfigService.mapAPColumnsToAdHocColumns(this.apConfigService.apConfig.accountsPayableSettingsColumns); } else { this.apSettingsColumns = null; } } setAudienceOptions () { this.audienceOptions = this.hasAudienceOptions ? this.arrayHelper.sort(this.audienceService.allAudiences .concat([{ id: null, name: this.noAudiencesText }] as Audience[]) .map((audience) => { return { value: audience.id, label: audience.name }; }), 'label') : [{ value: null, label: this.noAudiencesText }]; } setDestinationOptions () { const sftpOptions = this.sFTPService.basicCredentialsList .map((sftp) => { return { label: this.i18n.translate( 'reporting:textClientNameSecureStorage', { clientName: this.clientName }, '__clientName__ secure storage') + ' ' + sftp.siteName, value: sftp.id }; }); this.exportDestinationOptions = this.arrayHelper.sort( sftpOptions.concat( [{ value: 0, label: this.secureStorageText }]), 'label'); } async saveAPConfig () { const payload = { id: this.apConfigService.apConfig ? this.apConfigService.apConfig.id : null, sftpDetailsId: !!this.formGroup.value.exportDestination ? this.formGroup.value.exportDestination : null, audienceId: this.formGroup.value.audience, accountsPayableSettingsColumns: this.apSettingsColumns, exportFileTypeId: this.formGroup.value.exportFileTypeId }; await this.apConfigService.updateAPConfig(payload); } updateColumns (adHocOutput: AdHocReportingUI.ColumnImplementation[]) { const adapted = this.adaptAdHocOutput(adHocOutput); this.apSettingsColumns = adapted; } adaptAdHocOutput (adHocOutput: AdHocReportingUI.ColumnImplementation[]): APConfigAPI.APSettingsColumn[] { const adapted = adHocOutput.map((column, index) => { return { columnName: column.filterColumn.columnName, sortPriority: index + 1, suppliedColumnName: column.columnNameOverride, isVisible: true }; }); return adapted; } async importVendorIdsModal (isIndividual = false) { const contents = await this.modalFactory.open( ImportVendorModalComponent, { isIndividual } ); if (contents) { this.spinnerService.startSpinner(); await this.apConfigService.handleImportVendorIds(isIndividual, contents); this.spinnerService.stopSpinner(); } } ngOnDestroy () { this.footerState.set('footerState', this.footerState.FOOTER_STATES.STANDARD); this.footerState.set('footerAction', null); this.footerState.set('footerActionLabel', null); } }