Files
Aislo/Z01_MasterData/Z01_MasterData_UI_Cells.ts
T

71 lines
2.8 KiB
TypeScript

/* =============================================================================
* Z01_MasterData_UI_Cells.ts
* 마스터 표 칸 글자 — 숨김 열 · 열 제목 · 칸 값 · 쪽 수 (import 없음 · 시험이 그대로 돌림)
*
* 한글 이름은 API 가 `label` 로 줌(이름표 파일 `resources/data_master_labels/`) — 화면은
* 사전을 두지 않고 받은 대로 보임. 두 벌이 되면 어긋나기 때문(2026-09-15 브레인 Z01 ①).
* ========================================================================== */
export interface MasterColumn {
key: string;
label: string;
unit?: string | null;
/** 내부 id · sha · 생성시각 — 기본으로 안 보임 */
hidden?: boolean;
}
export function shownColumns(columns: MasterColumn[], showHidden: boolean): MasterColumn[] {
return showHidden ? columns : columns.filter((column) => !column.hidden);
}
export function columnTitle(column: MasterColumn): string {
return column.unit ? `${column.label} (${column.unit})` : column.label;
}
/** 단위가 붙은 수만 쉼표 — 연도·코드 같은 수(단위 없음)에 쉼표가 끼면 틀린 값처럼 보임. */
export function cellText(value: unknown, unit?: string | null): string {
if (value === null || value === undefined) return "";
if (typeof value === "boolean") return value ? "예" : "아니오";
if (typeof value === "number" && unit) {
return value.toLocaleString("ko-KR", { maximumFractionDigits: 10 });
}
if (typeof value === "object") return JSON.stringify(value);
return String(value);
}
/** 한 줄의 칸들 — columns 차례대로만(columns 에 없는 열은 안 그림) · 줄에 그 열이 없으면 「—」. */
export function rowCells(row: Record<string, unknown>, columns: MasterColumn[]): string[] {
return columns.map((column) =>
Object.hasOwn(row, column.key) ? cellText(row[column.key], column.unit) : "—",
);
}
export function pageCount(total: number, size: number): number {
return Math.max(1, Math.ceil(total / size));
}
/** 쪽 번호 칸에 적은 값을 1~끝 쪽으로 — 큰 표(800쪽)는 한 칸씩 넘길 수 없음. */
export function clampPage(value: number, pages: number): number {
return Number.isFinite(value) ? Math.min(pages, Math.max(1, Math.round(value))) : 1;
}
/**
* 최신 요청의 응답만 — 검색 글자가 바뀌어 옛 요청이 늦게 오면 새 표를 덮음.
* 옛 요청은 undefined 로 끝나고(오류도 삼킴) 최신 요청의 오류만 던짐.
*/
export function latestOnly<A extends unknown[], T>(
fn: (...args: A) => Promise<T>,
): (...args: A) => Promise<T | undefined> {
let seq = 0;
return async (...args) => {
const mine = ++seq;
try {
const value = await fn(...args);
return mine === seq ? value : undefined;
} catch (error) {
if (mine === seq) throw error;
return undefined;
}
};
}