import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute, RouterLink } from '@angular/router'; import { Danka } from '../../models/danka'; import { Family } from '../../models/family'; import { Kakocho } from '../../models/kakocho'; import { DankaService } from '../../services/dankaService'; import { FamilyService } from '../../services/family-service'; import { KakochoService } from '../../services/kakocho-service'; import { AppHeader } from '../../share/header/app-header'; import { AppSideMenu } from '../../share/side-menu/app-side-menu'; @Component({ selector: 'app-search', imports: [AppHeader, AppSideMenu, FormsModule, RouterLink], templateUrl: './search.html', styleUrl: './search.scss', }) export class Search implements OnInit{ searchKeyword = ''; selectedSearchType = 'all'; searchTypeFilters = [ { label: 'すべて', value: 'all' }, { label: '檀家(世帯)', value: 'danka' }, { label: '家族', value: 'family' }, { label: '過去帳', value: 'kakocho' }, ]; dankaResults: Danka[] = []; familyResults: Family[] = []; kakochoResults: Kakocho[] = []; totalResultCount = 0; private searchTimer?: ReturnType; private searchRequestId = 0; constructor( private dankaService: DankaService, private familyService: FamilyService, private kakochoService: KakochoService, private route: ActivatedRoute, private cdr: ChangeDetectorRef, ) { } ngOnInit(): void { const keyword = this.route.snapshot.queryParamMap.get('keyword'); if (keyword) { this.searchKeyword = keyword; this.submitSearch(); } } // フィルタータブの選択処理 changeSearchType(searchType: string): void { this.selectedSearchType = searchType; this.submitSearch(); } onSearchKeywordChange(keyword: string): void { this.searchKeyword = keyword; if (this.searchTimer) { clearTimeout(this.searchTimer); } this.searchTimer = setTimeout(() => { this.searchAll(); }, 250); } submitSearch(): void { if (this.searchTimer) { clearTimeout(this.searchTimer); } this.searchAll(); } // 全検索の処理 async searchAll(): Promise { const requestId = ++this.searchRequestId; const keyword = this.searchKeyword.trim(); const searchType = this.selectedSearchType; if (keyword === '') { this.setSearchResults([], [], [], requestId); return; } const [dankaList, familyList, kakochoList] = await Promise.all([ this.dankaService.getDankaList(), this.familyService.getFamilyList(), this.kakochoService.getKakochoList(), ]); if (requestId !== this.searchRequestId) { return; } let dankaResults: Danka[] = []; let familyResults: Family[] = []; let kakochoResults: Kakocho[] = []; // 檀家検索 if (searchType === 'all' || searchType === 'danka') { dankaResults = dankaList.filter((danka) => this.includesKeyword(danka.householdName, keyword) || this.includesKeyword(danka.householder, keyword) || this.includesKeyword(danka.postalCode, keyword) || this.includesKeyword(danka.address, keyword) || this.getPhones(danka).some( (phone) => this.includesKeyword(phone.tel, keyword) || this.includesKeyword(phone.note, keyword) ) ); } // 家族検索 if (searchType === 'all' || searchType === 'family') { familyResults = familyList.filter((family) => this.includesKeyword(family.name, keyword) || this.includesKeyword(family.furigana, keyword) || this.includesKeyword(family.relationship, keyword) || this.includesKeyword(family.birthDate, keyword) || this.includesKeyword(family.note, keyword) ); } // 過去帳検索 if (searchType === 'all' || searchType === 'kakocho') { kakochoResults = kakochoList.filter((kakocho) => this.includesKeyword(kakocho.name, keyword) || this.includesKeyword(kakocho.furigana, keyword) || this.includesKeyword(kakocho.relationship, keyword) || this.includesKeyword(kakocho.kaimyo, keyword) || this.includesKeyword(kakocho.deathDate, keyword) || this.includesKeyword(kakocho.ageAtDeath, keyword) || this.includesKeyword(kakocho.note, keyword) ); } this.setSearchResults(dankaResults, familyResults, kakochoResults, requestId); } clearSearch(): void { if (this.searchTimer) { clearTimeout(this.searchTimer); } this.searchRequestId++; this.searchKeyword = ''; this.selectedSearchType = 'all'; this.dankaResults = []; this.familyResults = []; this.kakochoResults = []; this.totalResultCount = 0; this.cdr.detectChanges(); } private includesKeyword(value: unknown, keyword: string): boolean { return String(value ?? '').includes(keyword); } private getPhones(danka: Danka) { return Array.isArray(danka.phones) ? danka.phones : []; } private setSearchResults( dankaResults: Danka[], familyResults: Family[], kakochoResults: Kakocho[], requestId: number, ): void { if (requestId !== this.searchRequestId) { return; } this.dankaResults = dankaResults; this.familyResults = familyResults; this.kakochoResults = kakochoResults; this.totalResultCount = dankaResults.length + familyResults.length + kakochoResults.length; this.cdr.detectChanges(); } }