import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { AbstractControl } from '@angular/forms'; import { InKindService } from '@features/in-kind/in-kind.service'; import { InKindCategory, InKindCategoryItemStat } from '@features/in-kind/in-kind.typing'; import { TypeaheadSelectOption, TypeSafeFormBuilder, TypeSafeFormGroup } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { Subscription } from 'rxjs'; export interface InKindItemSelectorFormGroup { allowMultiple: boolean; categories: InKindCategory[]; items: string[]; maxItems: number; showCategory: boolean; displayInKindValues: boolean; } export interface InKindDataSettingsChange { allowMultiple: boolean; maxItems: number; showCategory: boolean; items: string[]; displayInKindValues: boolean; } @Component({ selector: 'gc-in-kind-data-settings', templateUrl: './in-kind-data-settings.component.html', styleUrls: ['./in-kind-data-settings.component.scss'] }) export class InKindDataSettingsComponent implements OnInit, OnDestroy { @Input() allowMultiple: boolean; @Input() maxItems: number; @Input() showCategory: boolean; @Input() items: string[]; @Input() displayInKindValues: boolean; @Output() isValidChange = new EventEmitter(); @Output() onChange = new EventEmitter(); itemOptions: TypeaheadSelectOption[] = []; formGroup: TypeSafeFormGroup; categories = this.inKindService.categories.map((cat) => { return { label: cat.name, value: cat }; }); sub = new Subscription(); constructor ( private inKindService: InKindService, private formBuilder: TypeSafeFormBuilder, private i18n: I18nService ) { } ngOnInit () { this.setItems(); this.formGroup = this.formBuilder.group({ allowMultiple: this.allowMultiple, maxItems: this.maxItems, showCategory: this.showCategory, categories: [[]], items: [this.items, this.itemsValidator()], displayInKindValues: this.displayInKindValues }); this.sub.add(this.formGroup.statusChanges.subscribe(() => { this.isValidChange.emit(this.formGroup.valid); })); } itemsValidator () { return (control: AbstractControl) => { const items: string[] = control.value; if (items?.length < 1) { return { mustSelectAtLeastOneItem: { i18nKey: 'common:textMustSelectAtLeastOneItem', defaultValue: 'Must select at least one item' } }; } return null; }; } setItems () { if (!this.items) { this.items = []; } const map = this.inKindService.categoryItemMap; const selectedCategories = this.formGroup ? this.formGroup.value.categories : []; const categories = selectedCategories?.length > 0 ? selectedCategories : this.inKindService.categories; this.itemOptions = categories.reduce((acc, key) => { const items = map[key.id].filter((item) => { if (!item.inUse) { return this.items.includes(item.identification); } return item; }); return [ ...acc, ...items ]; }, []).map(item => { const itemNoLongerActive = this.i18n.translate( 'BUDGET:textItemNoLongerActive', {}, 'Item no longer active' ); return { label: `${item.name}${ item.inUse ? '' : ' (' + itemNoLongerActive + ')'}`, value: item.identification }; }); } onSettingsChange () { const formVal = this.formGroup.value; this.onChange.emit({ allowMultiple: formVal.allowMultiple, maxItems: formVal.maxItems, showCategory: formVal.showCategory, items: formVal.items, displayInKindValues: formVal.displayInKindValues }); } ngOnDestroy () { this.sub.unsubscribe(); } }