|
|
@@ -1,4 +1,4 @@
|
|
1
|
|
-import { Component, OnInit } from '@angular/core';
|
|
|
1
|
+import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
|
2
|
2
|
import { FormsModule } from '@angular/forms';
|
|
3
|
3
|
import { DankaService } from '../../services/dankaService';
|
|
4
|
4
|
import { FamilyService } from '../../services/family-service';
|
|
|
@@ -15,6 +15,7 @@ import { AppSideMenu } from '../../share/side-menu/app-side-menu';
|
|
15
|
15
|
})
|
|
16
|
16
|
export class EventPage implements OnInit{
|
|
17
|
17
|
eventTargets: EventTarget[] = [];
|
|
|
18
|
+ isLoading = true;
|
|
18
|
19
|
targetYear: number = new Date().getFullYear();
|
|
19
|
20
|
selectedEventType: EventType | 'all' = 'all';
|
|
20
|
21
|
selectedStatus: EventStatus | 'all' = 'all';
|
|
|
@@ -38,11 +39,13 @@ export class EventPage implements OnInit{
|
|
38
|
39
|
{ label: '未案内', value: '未案内' },
|
|
39
|
40
|
{ label: '案内済', value: '案内済' },
|
|
40
|
41
|
];
|
|
|
42
|
+ private eventRequestId = 0;
|
|
41
|
43
|
|
|
42
|
44
|
constructor(
|
|
43
|
45
|
private dankaService: DankaService,
|
|
44
|
46
|
private familyService: FamilyService,
|
|
45
|
47
|
private eventService: EventService,
|
|
|
48
|
+ private cdr: ChangeDetectorRef,
|
|
46
|
49
|
) { }
|
|
47
|
50
|
|
|
48
|
51
|
ngOnInit(): void {
|
|
|
@@ -54,7 +57,15 @@ export class EventPage implements OnInit{
|
|
54
|
57
|
}
|
|
55
|
58
|
|
|
56
|
59
|
async createEventTargetList(): Promise<void> {
|
|
57
|
|
- this.eventTargets = [];
|
|
|
60
|
+ const requestId = ++this.eventRequestId;
|
|
|
61
|
+ const targetYear = this.targetYear;
|
|
|
62
|
+ const selectedEventType = this.selectedEventType;
|
|
|
63
|
+ const eventTargets: EventTarget[] = [];
|
|
|
64
|
+
|
|
|
65
|
+ if (this.eventTargets.length === 0) {
|
|
|
66
|
+ this.isLoading = true;
|
|
|
67
|
+ this.cdr.detectChanges();
|
|
|
68
|
+ }
|
|
58
|
69
|
|
|
59
|
70
|
const families = await this.familyService.getFamilyList();
|
|
60
|
71
|
|
|
|
@@ -62,7 +73,7 @@ export class EventPage implements OnInit{
|
|
62
|
73
|
const birthDate = this.parseDate(family.birthDate);
|
|
63
|
74
|
if (!birthDate) continue;
|
|
64
|
75
|
|
|
65
|
|
- const age = this.targetYear - birthDate.getFullYear();
|
|
|
76
|
+ const age = targetYear - birthDate.getFullYear();
|
|
66
|
77
|
const eventTypes = this.getEventTypes(age);
|
|
67
|
78
|
if (eventTypes.length === 0) continue;
|
|
68
|
79
|
|
|
|
@@ -71,8 +82,8 @@ export class EventPage implements OnInit{
|
|
71
|
82
|
|
|
72
|
83
|
for (const eventType of eventTypes) {
|
|
73
|
84
|
if (
|
|
74
|
|
- this.selectedEventType !== 'all' &&
|
|
75
|
|
- this.selectedEventType !== eventType
|
|
|
85
|
+ selectedEventType !== 'all' &&
|
|
|
86
|
+ selectedEventType !== eventType
|
|
76
|
87
|
) {
|
|
77
|
88
|
continue;
|
|
78
|
89
|
}
|
|
|
@@ -82,14 +93,14 @@ export class EventPage implements OnInit{
|
|
82
|
93
|
const defaultStatus: EventStatus =
|
|
83
|
94
|
Number(family.id) % 2 === 0 ? '案内済' : '未案内';
|
|
84
|
95
|
|
|
85
|
|
- this.eventTargets.push({
|
|
|
96
|
+ eventTargets.push({
|
|
86
|
97
|
id,
|
|
87
|
98
|
dankaId: family.dankaId,
|
|
88
|
99
|
name: family.name,
|
|
89
|
100
|
furigana: family.furigana,
|
|
90
|
101
|
householdName: danka?.householdName ?? '不明',
|
|
91
|
102
|
relationship: family.relationship || '未登録',
|
|
92
|
|
- birthDate: family.birthDate,
|
|
|
103
|
+ birthDate: this.formatDateForValue(birthDate),
|
|
93
|
104
|
age,
|
|
94
|
105
|
eventType,
|
|
95
|
106
|
note: family.note,
|
|
|
@@ -98,13 +109,19 @@ export class EventPage implements OnInit{
|
|
98
|
109
|
}
|
|
99
|
110
|
}
|
|
100
|
111
|
|
|
101
|
|
- this.eventTargets.sort(
|
|
|
112
|
+ if (requestId !== this.eventRequestId) {
|
|
|
113
|
+ return;
|
|
|
114
|
+ }
|
|
|
115
|
+
|
|
|
116
|
+ this.eventTargets = eventTargets.sort(
|
|
102
|
117
|
(a, b) =>
|
|
103
|
118
|
this.getEventSortOrder(a.eventType) -
|
|
104
|
119
|
this.getEventSortOrder(b.eventType) ||
|
|
105
|
120
|
a.age - b.age ||
|
|
106
|
121
|
a.name.localeCompare(b.name, 'ja'),
|
|
107
|
122
|
);
|
|
|
123
|
+ this.isLoading = false;
|
|
|
124
|
+ this.cdr.detectChanges();
|
|
108
|
125
|
}
|
|
109
|
126
|
|
|
110
|
127
|
changeEventType(eventType: EventType | 'all'): void {
|
|
|
@@ -128,7 +145,7 @@ export class EventPage implements OnInit{
|
|
128
|
145
|
target.eventType,
|
|
129
|
146
|
target.note,
|
|
130
|
147
|
target.status,
|
|
131
|
|
- ].some((value) => value.includes(keyword));
|
|
|
148
|
+ ].some((value) => this.includesKeyword(value, keyword));
|
|
132
|
149
|
|
|
133
|
150
|
return matchesStatus && matchesKeyword;
|
|
134
|
151
|
});
|
|
|
@@ -162,11 +179,38 @@ export class EventPage implements OnInit{
|
|
162
|
179
|
return ['稚児行列', '七五三', '成人式', '米寿'].indexOf(eventType);
|
|
163
|
180
|
}
|
|
164
|
181
|
|
|
165
|
|
- private parseDate(value: string): Date | null {
|
|
|
182
|
+ private parseDate(value: unknown): Date | null {
|
|
|
183
|
+ if (!value) {
|
|
|
184
|
+ return null;
|
|
|
185
|
+ }
|
|
|
186
|
+
|
|
|
187
|
+ if (value instanceof Date) {
|
|
|
188
|
+ return value;
|
|
|
189
|
+ }
|
|
|
190
|
+
|
|
|
191
|
+ if (typeof value === 'object' && 'toDate' in value && typeof value.toDate === 'function') {
|
|
|
192
|
+ return value.toDate();
|
|
|
193
|
+ }
|
|
|
194
|
+
|
|
|
195
|
+ if (typeof value !== 'string') {
|
|
|
196
|
+ return null;
|
|
|
197
|
+ }
|
|
|
198
|
+
|
|
166
|
199
|
const [year, month, day] = value.split('-').map(Number);
|
|
167
|
200
|
if (!year || !month || !day) {
|
|
168
|
201
|
return null;
|
|
169
|
202
|
}
|
|
170
|
203
|
return new Date(year, month - 1, day);
|
|
171
|
204
|
}
|
|
|
205
|
+
|
|
|
206
|
+ private includesKeyword(value: unknown, keyword: string): boolean {
|
|
|
207
|
+ return String(value ?? '').includes(keyword);
|
|
|
208
|
+ }
|
|
|
209
|
+
|
|
|
210
|
+ private formatDateForValue(date: Date): string {
|
|
|
211
|
+ const year = date.getFullYear();
|
|
|
212
|
+ const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
213
|
+ const day = String(date.getDate()).padStart(2, '0');
|
|
|
214
|
+ return `${year}-${month}-${day}`;
|
|
|
215
|
+ }
|
|
172
|
216
|
}
|