feat(i18n): compute bilingual label on giving/ministry/expense-category lookups
This commit is contained in:
@@ -5,10 +5,10 @@ export interface PagedResult<T> {
|
|||||||
items: T[]; totalCount: number; page: number; pageSize: number; totalPages: number;
|
items: T[]; totalCount: number; page: number; pageSize: number; totalPages: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MinistryDto { id: number; name_en: string; name_zh: string | null; sortOrder: number; isActive: boolean; }
|
export interface MinistryDto { id: number; name_en: string; name_zh: string | null; sortOrder: number; isActive: boolean; label?: string; }
|
||||||
|
|
||||||
export interface ExpenseSubCategoryDto { id: number; groupId: number; name_en: string; name_zh: string | null; sortOrder: number; isActive: boolean; }
|
export interface ExpenseSubCategoryDto { id: number; groupId: number; name_en: string; name_zh: string | null; sortOrder: number; isActive: boolean; label?: string; }
|
||||||
export interface ExpenseCategoryGroupDto { id: number; name_en: string; name_zh: string | null; sortOrder: number; isActive: boolean; subCategories: ExpenseSubCategoryDto[]; }
|
export interface ExpenseCategoryGroupDto { id: number; name_en: string; name_zh: string | null; sortOrder: number; isActive: boolean; subCategories: ExpenseSubCategoryDto[]; label?: string; }
|
||||||
export interface CreateExpenseGroupRequest { name_en: string; name_zh: string | null; sortOrder: number; }
|
export interface CreateExpenseGroupRequest { name_en: string; name_zh: string | null; sortOrder: number; }
|
||||||
export interface UpdateExpenseGroupRequest extends CreateExpenseGroupRequest { isActive: boolean; }
|
export interface UpdateExpenseGroupRequest extends CreateExpenseGroupRequest { isActive: boolean; }
|
||||||
export interface CreateExpenseSubCategoryRequest { groupId: number; name_en: string; name_zh: string | null; sortOrder: number; }
|
export interface CreateExpenseSubCategoryRequest { groupId: number; name_en: string; name_zh: string | null; sortOrder: number; }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, map } from 'rxjs';
|
||||||
|
import { bilingual } from '../../../shared/i18n/bilingual';
|
||||||
import { ApiConfigService } from '../../../core/services/api-config.service';
|
import { ApiConfigService } from '../../../core/services/api-config.service';
|
||||||
import {
|
import {
|
||||||
ExpenseCategoryGroupDto, CreateExpenseGroupRequest, UpdateExpenseGroupRequest,
|
ExpenseCategoryGroupDto, CreateExpenseGroupRequest, UpdateExpenseGroupRequest,
|
||||||
@@ -14,7 +15,13 @@ export class ExpenseCategoryApiService {
|
|||||||
this.endpoint = apiConfig.getApiUrl('expense-categories');
|
this.endpoint = apiConfig.getApiUrl('expense-categories');
|
||||||
}
|
}
|
||||||
getAll(includeInactive = false): Observable<ExpenseCategoryGroupDto[]> {
|
getAll(includeInactive = false): Observable<ExpenseCategoryGroupDto[]> {
|
||||||
return this.http.get<ExpenseCategoryGroupDto[]>(this.endpoint, { params: new HttpParams().set('includeInactive', includeInactive) });
|
return this.http.get<ExpenseCategoryGroupDto[]>(this.endpoint, { params: new HttpParams().set('includeInactive', includeInactive) }).pipe(
|
||||||
|
map(groups => groups.map(g => ({
|
||||||
|
...g,
|
||||||
|
label: bilingual(g.name_en, g.name_zh),
|
||||||
|
subCategories: g.subCategories.map(s => ({ ...s, label: bilingual(s.name_en, s.name_zh) })),
|
||||||
|
}))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
createGroup(r: CreateExpenseGroupRequest): Observable<{ id: number }> { return this.http.post<{ id: number }>(`${this.endpoint}/groups`, r); }
|
createGroup(r: CreateExpenseGroupRequest): Observable<{ id: number }> { return this.http.post<{ id: number }>(`${this.endpoint}/groups`, r); }
|
||||||
updateGroup(id: number, r: UpdateExpenseGroupRequest): Observable<void> { return this.http.put<void>(`${this.endpoint}/groups/${id}`, r); }
|
updateGroup(id: number, r: UpdateExpenseGroupRequest): Observable<void> { return this.http.put<void>(`${this.endpoint}/groups/${id}`, r); }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, map } from 'rxjs';
|
||||||
|
import { bilingual } from '../../../shared/i18n/bilingual';
|
||||||
import { ApiConfigService } from '../../../core/services/api-config.service';
|
import { ApiConfigService } from '../../../core/services/api-config.service';
|
||||||
import { MinistryDto } from '../models/expense.model';
|
import { MinistryDto } from '../models/expense.model';
|
||||||
|
|
||||||
@@ -11,6 +12,8 @@ export class MinistryApiService {
|
|||||||
this.endpoint = apiConfig.getApiUrl('ministries');
|
this.endpoint = apiConfig.getApiUrl('ministries');
|
||||||
}
|
}
|
||||||
getAll(includeInactive = false): Observable<MinistryDto[]> {
|
getAll(includeInactive = false): Observable<MinistryDto[]> {
|
||||||
return this.http.get<MinistryDto[]>(this.endpoint, { params: new HttpParams().set('includeInactive', includeInactive) });
|
return this.http.get<MinistryDto[]>(this.endpoint, { params: new HttpParams().set('includeInactive', includeInactive) }).pipe(
|
||||||
|
map(list => list.map(m => ({ ...m, label: bilingual(m.name_en, m.name_zh) }))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ export interface GivingCategoryDto {
|
|||||||
description_zh: string | null;
|
description_zh: string | null;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
sortOrder: number;
|
sortOrder: number;
|
||||||
|
/** Display-only bilingual label, computed in the API service. */
|
||||||
|
label?: string;
|
||||||
}
|
}
|
||||||
export interface CreateGivingCategoryRequest {
|
export interface CreateGivingCategoryRequest {
|
||||||
name_en: string;
|
name_en: string;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, map } from 'rxjs';
|
||||||
|
import { bilingual } from '../../../shared/i18n/bilingual';
|
||||||
import { ApiConfigService } from '../../../core/services/api-config.service';
|
import { ApiConfigService } from '../../../core/services/api-config.service';
|
||||||
import {
|
import {
|
||||||
GivingCategoryDto, CreateGivingCategoryRequest, UpdateGivingCategoryRequest,
|
GivingCategoryDto, CreateGivingCategoryRequest, UpdateGivingCategoryRequest,
|
||||||
@@ -15,7 +16,9 @@ export class GivingCategoryApiService {
|
|||||||
|
|
||||||
getAll(includeInactive = false): Observable<GivingCategoryDto[]> {
|
getAll(includeInactive = false): Observable<GivingCategoryDto[]> {
|
||||||
const params = new HttpParams().set('includeInactive', includeInactive);
|
const params = new HttpParams().set('includeInactive', includeInactive);
|
||||||
return this.http.get<GivingCategoryDto[]>(this.endpoint, { params });
|
return this.http.get<GivingCategoryDto[]>(this.endpoint, { params }).pipe(
|
||||||
|
map(list => list.map(c => ({ ...c, label: bilingual(c.name_en, c.name_zh) }))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
create(request: CreateGivingCategoryRequest): Observable<{ id: number }> {
|
create(request: CreateGivingCategoryRequest): Observable<{ id: number }> {
|
||||||
return this.http.post<{ id: number }>(this.endpoint, request);
|
return this.http.post<{ id: number }>(this.endpoint, request);
|
||||||
|
|||||||
Reference in New Issue
Block a user