import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { TimeZoneService } from '@core/services/time-zone.service'; import { TranslationService } from '@core/services/translation.service'; import { CyclesAPI } from '@core/typings/api/cycles.typing'; import { Program, ProgramTypes } from '@core/typings/program.typing'; import { CyclesUI } from '@core/typings/ui/cycles.typing'; import { ApplicationManagerResources } from '@features/application-manager/resources/application-manager.resources'; import { CyclesService } from '@features/cycles/cycles.service'; import { ProgramService } from '@features/programs/program.service'; import { ArrayHelpersService, TypeaheadSelectOption, TypeSafeFormBuilder, TypeSafeFormGroup } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; interface ProgramFormGroup { programId: number; cycleId: number; } @Component({ selector: 'gc-grant-program', templateUrl: './grant-program.component.html', styleUrls: ['./grant-program.component.scss'] }) export class GrantProgramComponent implements OnInit { @Input() isNomination: boolean; @Input() applicationId: number; @Input() programId: number; @Input() cycleId: number; @Input() canEditProgram: boolean; @Output() onProgramIdChange = new EventEmitter(); @Output() onCycleIdChange = new EventEmitter(); programCycles: CyclesAPI.BaseProgramCycle[]; programTimezoneId: string; formGroup: TypeSafeFormGroup; programOptions: TypeaheadSelectOption[] = []; cycleOptions: TypeaheadSelectOption[] = []; programs = this.programService.allActiveManagerPrograms; isNew: boolean; viewTranslations = this.translationService.viewTranslations; programTranslationMap = this.viewTranslations.Grant_Program; cycleTranslationMap = this.viewTranslations.Grant_Program_Cycle; cycle: CyclesUI.ProgramCycle; constructor ( private formBuilder: TypeSafeFormBuilder, private i18n: I18nService, private arrayHelper: ArrayHelpersService, private programService: ProgramService, private translationService: TranslationService, private cyclesService: CyclesService, private applicationManagerResources: ApplicationManagerResources, private timeZoneService: TimeZoneService ) { } async ngOnInit () { this.isNew = !this.applicationId; this.setProgramInfo(); this.formGroup = this.formBuilder.group({ programId: this.programId, cycleId: this.cycleId }); this.setProgramOptions(); this.setCycleOptions(); } setProgramInfo () { if (this.programId) { const found = this.programs.find((prog) => { return +prog.grantProgramId === this.programId; }); this.programTimezoneId = found?.timezoneId ?? 'UTC'; this.programCycles = found?.grantProgramCycles ?? []; } else { this.programTimezoneId = 'UTC'; this.programCycles = []; } } getDateString (start: string, end: string, timezoneId = 'UTC') { const programTimeZone = this.timeZoneService.returnTimeZoneFromID(timezoneId); const startDisplay = this.timeZoneService.adaptDateForDisplayIfDST( start, programTimeZone.offset ); const endDisplay = this.timeZoneService.adaptDateForDisplayIfDST( end, programTimeZone.offset ); return this.i18n.translate( 'common:textDateToDate', { start: startDisplay, end: endDisplay }, '__start__ to __end__' ); } setProgramOptions () { const options = this.programs.filter((prog) => { return this.isNomination ? prog.programType === ProgramTypes.NOMINATION : prog.programType === ProgramTypes.GRANT; }).map((prog: Program) => { const dateString = this.getDateString( prog.startDate, prog.endDate, prog.timezoneId ); const name = this.programTranslationMap[prog.grantProgramId] ? this.programTranslationMap[prog.grantProgramId].Name : prog.grantProgramName; return { option: `
${name}
${dateString}
${ prog.timezoneId || 'UTC' }
`, value: prog.grantProgramId, label: name }; }); this.programOptions = this.arrayHelper.sort(options, 'label'); } async setCycleOptions () { if (this.programId) { let eligibleCycleIds: number[]; if (!this.isNew) { const payload = { programId: this.programId, applicationIds: [this.applicationId] }; const response = await this.applicationManagerResources.getUpdateCycleInfo( payload ); eligibleCycleIds = response.eligibleCycleIds; } this.cycleOptions = this.programCycles.filter((cycle) => { return eligibleCycleIds ? eligibleCycleIds.includes(cycle.id) : true; }).map((cycle) => { const dateString = this.getDateString( cycle.startDate, cycle.endDate, this.programTimezoneId ); const obj = this.cycleTranslationMap[cycle.id]; const cycleName = obj && obj.Name ? obj.Name : cycle.name; return { option: `
${cycleName}
${dateString}
${ this.programTimezoneId || 'UTC' }
`, value: cycle.id, label: cycleName }; }); if (!this.cycleId) { const firstCycleId = this.cycleOptions[0].value; if (this.cycleOptions.length === 1) { this.updateCycle(firstCycleId); } else { // Find active cycle const helpers = this.cyclesService.getCycleDateHelpers( this.programCycles ); const cycleToSet = helpers.currentCycle || helpers.nextCycle || helpers.lastCycle; this.updateCycle(cycleToSet.id || firstCycleId); } } } else { this.cycleOptions = []; } } updateCycle (cycleId: number) { this.formGroup.get('cycleId').setValue(cycleId); this.setCycle(); } setProgram () { this.programId = this.formGroup.value.programId; this.setProgramInfo(); this.onProgramIdChange.emit(this.programId); if (this.formGroup.value.cycleId) { this.updateCycle(null); } this.setCycleOptions(); } setCycle () { this.cycleId = this.formGroup.value.cycleId; this.onCycleIdChange.emit(this.cycleId); } }