import { Injectable } from '@angular/core'; import { ClassificationState } from '@core/states/classification.state'; import classifications from '@core/static-assets/classifications'; import { ArrayHelpersService, Classification, ClassificationFromApi, ClassificationMaps, InflectService, SimpleStringMap } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { AttachYCState, BaseYCService } from '@yourcause/common/state'; import findKey from 'lodash/findKey'; @AttachYCState(ClassificationState) @Injectable({ providedIn: 'root' }) export class ClassificationService extends BaseYCService { constructor ( private i18n: I18nService, private inflect: InflectService, private arrayHelper: ArrayHelpersService ) { super(); } get classificationOptions () { return this.get('classificationOptions'); } get classificationMap () { return this.get('classificationMap'); } setClassifications () { if (!this.classificationMap) { const adapted = this.buildHierarchy(classifications as ClassificationFromApi[]); this.set('classificationMap', adapted); this.setClassificationOptions(adapted.hierarchicalMap); } } setClassificationOptions (map: SimpleStringMap) { const options = Object.keys(map).map((key) => { const classification = map[key]; return { label: this.i18n.translate( `classification:text${this.inflect.pascalize(classification.name)}`, {}, classification.name ), value: classification.id }; }); this.set( 'classificationOptions', this.arrayHelper.sort(options, 'label') ); } buildHierarchy (list: ClassificationFromApi[]): ClassificationMaps { const adaptedList: Classification[] = []; const hierarchicalMap: { [x: string]: Classification } = {}; const childMap: { [x: string]: Classification } = {}; const flatMap = list.reduce((map, classification) => { const adapted = { ...classification } as Classification; adapted.code = (adapted.code || '').trim(); adapted.parentCode = (adapted.parentCode || '').trim(); adapted.display = this.i18n.translate( `classification:text${this.inflect.pascalize(adapted.name)}`, {}, adapted.name ); adapted.value = adapted; adapted.children = map[adapted.code] ? map[adapted.code].children : []; map[adapted.code] = adapted; if (adapted.parentCode) { map[adapted.parentCode] = map[adapted.parentCode] || { children: [] } as Classification; map[adapted.parentCode].children.push(adapted); childMap[adapted.code] = adapted; } else { classification.isRoot = true; hierarchicalMap[adapted.code] = adapted; } adaptedList.push(adapted); return map; }, {} as { [x: string]: Classification }); return { childMap, hierarchicalMap, flatMap, list: adaptedList }; } getIconFromSearchResult (org: { iconURL?: string; classification?: string; }) { if (org.iconURL) { return org.iconURL; } const id = findKey(this.classificationMap.flatMap, { name: org.classification }); return `assets/img/nonprofit/icons/cat_${id || 10}.gif`; } }