import { HttpErrorResponse } from '@angular/common/http'; import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { SpinnerService } from '@core/services/spinner.service'; import { OpenCloseBudgetAPI } from '@core/typings/api/open-close-budget.typing'; import { Budget, BudgetDrilldownInfo, FundingSourceTypes } from '@core/typings/budget.typing'; import { ClientSettingsService } from '@features/client-settings/client-settings.service'; import { BulkAction, TopLevelFilter } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { LogService } from '@yourcause/common/logging'; import { ConfirmationModalComponent, ModalFactory } from '@yourcause/common/modals'; import { NotifierService } from '@yourcause/common/notifier'; import { BudgetResources } from '../budget.resources'; import { BudgetService } from '../budget.service'; import { OpenCloseBudgetModalComponent } from '../open-close-budget-modal/open-close-budget-modal.component'; @Component({ selector: 'gc-budgets-page', templateUrl: 'budgets-page.component.html', styleUrls: ['./budgets-page.component.scss'] }) export class BudgetsPageComponent { topLevelFilters = [ new TopLevelFilter( 'text', 'name', '', this.i18n.translate( 'common:textSearchByName', {}, 'Search by name' ) ) ]; bulkActions: BulkAction[] = this.router.url.includes('open') ? [{ exec: async (budgets: Budget[]) => { await this.doOpenBudgetOpenCloseModal(budgets, 'close', null); }, disabled: () => false, label: this.i18n.translate('common:textClose', {}, 'Close') }] : []; FundingSourceTypes = FundingSourceTypes; drilldownInfo: BudgetDrilldownInfo; budgets$ = this.router.url.includes('open') ? this.budgetService.changesTo$('openBudgets') : this.budgetService.changesTo$('closedBudgets'); constructor ( private logger: LogService, private i18n: I18nService, private modalFactory: ModalFactory, private router: Router, private spinnerService: SpinnerService, private budgetService: BudgetService, private clientSettingsService: ClientSettingsService, private notifier: NotifierService, private budgetResources: BudgetResources ) { } get canReserveFunds () { return this.clientSettingsService.get('clientSettings').reserveFunds; } async onDrilldown (row: Budget) { this.drilldownInfo = null; const drilldownInfo = await this.budgetService.getBudgetDrilldownInfo(row.id); this.drilldownInfo = drilldownInfo; } async removeBudget (row: Budget) { const deps = { modalHeader: this.i18n.translate( 'BUDGET:hdrDeleteBudget' ), modalSubHeader: row.name, confirmButtonText: this.i18n.translate( 'common:btnDelete', {}, 'Delete' ), confirmText: this.i18n.translate( 'BUDGET:textAreYouSureDeleteBudget', {}, 'Are you sure you want to delete this budget?' ) }; const proceed = await this.modalFactory.open( ConfirmationModalComponent, deps ); if (proceed) { this.spinnerService.startSpinner(); try { await this.budgetResources.deleteBudget(row.id); await this.budgetService.resetBudgets(); await this.budgetService.resetFundingSources(); this.notifier.success(this.i18n.translate( 'BUDGET:textSuccessfullyDeletedBudget', {}, 'Successfully deleted the budget' )); } catch (err) { const e = err as HttpErrorResponse; this.logger.error(e); if ( e.error && e.error.message.includes( 'This budget is currently tied to the following Grant Program(s)' ) ) { this.notifier.error(this.i18n.translate( 'BUDGET:textErrorDeletingBudgetRelatedToProgram', {}, 'This budget cannot be deleted because it is currently related to one or more grant programs.' )); } else { this.notifier.error(this.i18n.translate( 'BUDGET:textErrorDeletingBudget', {}, 'There was an error deleting the budget' )); } } this.spinnerService.stopSpinner(); } } async openCloseBudgetModal (context: 'open'|'close', budget: Budget) { this.spinnerService.startSpinner(); const budgetDetails = await this.budgetService.getBudgetDrilldownInfo( budget.id ); this.spinnerService.stopSpinner(); await this.doOpenBudgetOpenCloseModal([budget], context, budgetDetails); } private async doOpenBudgetOpenCloseModal ( budgets: Budget[], context: 'open'|'close', budgetDetails?: BudgetDrilldownInfo ) { const response = await this.modalFactory.open( OpenCloseBudgetModalComponent, { budgets, context, budgetDetails } ); if (response) { switch (context) { case 'open': await this.budgetService.openBudget(response as number); break; case 'close': await this.budgetService.closeBudget(response as OpenCloseBudgetAPI.CloseBudgetPayload); break; } } } }