92 lines
3.0 KiB
TypeScript
92 lines
3.0 KiB
TypeScript
import { ValueType } from "realgrid";
|
|
|
|
import type { ColumnConfig, ColumnInfo } from "@/components/type/DataGrid.type";
|
|
import type { StatisticsLogDetailRow } from "@/entities/statistics/model/statistics-interface";
|
|
|
|
const COMMON_FIELD_ORDER = ["rmrk", "sggNm", "admdstCd", "admdstNm"] as const;
|
|
|
|
const FIELD_HEADER: Record<string, string> = {
|
|
rmrk: "비고",
|
|
sggNm: "시군구",
|
|
admdstCd: "행정구역코드",
|
|
admdstNm: "행정구역명",
|
|
};
|
|
|
|
function collectFieldNames(rows: StatisticsLogDetailRow[]): string[] {
|
|
const keys = new Set<string>();
|
|
for (const row of rows) {
|
|
for (const key of Object.keys(row)) {
|
|
keys.add(key);
|
|
}
|
|
}
|
|
const common = COMMON_FIELD_ORDER.filter((k) => keys.has(k));
|
|
const rest = [...keys]
|
|
.filter((k) => !COMMON_FIELD_ORDER.includes(k as (typeof COMMON_FIELD_ORDER)[number]))
|
|
.sort((a, b) => a.localeCompare(b, "ko"));
|
|
return [...common, ...rest];
|
|
}
|
|
|
|
function isNumericField(rows: StatisticsLogDetailRow[], fieldName: string): boolean {
|
|
return rows.some((row) => {
|
|
const v = row[fieldName];
|
|
return typeof v === "number" && !Number.isNaN(v);
|
|
});
|
|
}
|
|
|
|
function buildColumns(rows: StatisticsLogDetailRow[]): ColumnConfig[] {
|
|
const fieldNames = collectFieldNames(rows);
|
|
if (fieldNames.length === 0) {
|
|
return COMMON_FIELD_ORDER.map((fieldName) => ({
|
|
name: fieldName,
|
|
fieldName,
|
|
header: { text: FIELD_HEADER[fieldName] ?? fieldName },
|
|
editable: false,
|
|
width: Math.min(340, Math.max(90, fieldName.length * 9 + 28))
|
|
}));
|
|
}
|
|
|
|
return fieldNames.map((fieldName) => {
|
|
const numeric = isNumericField(rows, fieldName);
|
|
return {
|
|
name: fieldName,
|
|
fieldName,
|
|
header: { text: FIELD_HEADER[fieldName] ?? fieldName },
|
|
editable: false,
|
|
valueType: numeric ? ValueType.NUMBER : undefined,
|
|
dataFormat: numeric ? "#,##0.###" : undefined,
|
|
width: Math.min(340, Math.max(90, fieldName.length * 9 + 28)),
|
|
visible: fieldName !== "admdstCd",
|
|
};
|
|
});
|
|
}
|
|
|
|
export function buildLogHistoryDetailColumnInfo(
|
|
rows: StatisticsLogDetailRow[],
|
|
): ColumnInfo {
|
|
const columns = buildColumns(rows);
|
|
return {
|
|
columns,
|
|
columnLayout: columns.map((c) => c.fieldName),
|
|
};
|
|
}
|
|
|
|
/** 그리드 field 정의와 행 키를 맞춤 (누락 필드 → "") */
|
|
export function alignLogDetailRowsToColumns(
|
|
rows: Record<string, string | number>[],
|
|
columnInfo: ColumnInfo,
|
|
): Record<string, string | number>[] {
|
|
const fieldNames = columnInfo.columns.map((c) => c.fieldName);
|
|
return rows.map((row) => {
|
|
const aligned: Record<string, string | number> = {};
|
|
for (const fieldName of fieldNames) {
|
|
const value = row[fieldName];
|
|
aligned[fieldName] =
|
|
value === null || value === undefined ? "" : value;
|
|
}
|
|
return aligned;
|
|
});
|
|
}
|
|
|
|
export const emptyLogHistoryDetailColumnInfo =
|
|
buildLogHistoryDetailColumnInfo([]);
|