refactor(WEB): DataTable 개선 및 회계 상세 컴포넌트 리팩토링
- DataTable 컴포넌트 기능 확장 및 코드 개선 - 회계 상세 컴포넌트(Bill/Deposit/Purchase/Sales/Withdrawal) 리팩토링 - 엑셀 다운로드 유틸리티 개선 - 대시보드 및 각종 리스트 페이지 업데이트 - dashboard_type2 페이지 추가 - 프론트엔드 개선 로드맵 문서 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,11 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
// xlsx는 ~400KB로 무거워서, 실제 사용 시점에 동적 로드
|
||||
async function loadXLSX() {
|
||||
const XLSX = await import('xlsx');
|
||||
return XLSX;
|
||||
}
|
||||
|
||||
/**
|
||||
* 엑셀 컬럼 정의
|
||||
@@ -84,19 +88,21 @@ function generateFilename(baseName: string, appendDate: boolean): string {
|
||||
/**
|
||||
* 데이터를 엑셀 파일로 다운로드
|
||||
*/
|
||||
export function downloadExcel<T extends Record<string, unknown>>({
|
||||
export async function downloadExcel<T extends Record<string, unknown>>({
|
||||
data,
|
||||
columns,
|
||||
filename = 'export',
|
||||
sheetName = 'Sheet1',
|
||||
appendDate = true,
|
||||
}: ExcelDownloadOptions<T>): void {
|
||||
}: ExcelDownloadOptions<T>): Promise<void> {
|
||||
if (!data || data.length === 0) {
|
||||
console.warn('[Excel] 다운로드할 데이터가 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const XLSX = await loadXLSX();
|
||||
|
||||
// 1. 헤더 행 생성
|
||||
const headers = columns.map((col) => col.header);
|
||||
|
||||
@@ -162,7 +168,7 @@ export function downloadExcel<T extends Record<string, unknown>>({
|
||||
/**
|
||||
* 선택된 항목만 엑셀로 다운로드
|
||||
*/
|
||||
export function downloadSelectedExcel<T extends Record<string, unknown>>({
|
||||
export async function downloadSelectedExcel<T extends Record<string, unknown>>({
|
||||
data,
|
||||
selectedIds,
|
||||
idField = 'id',
|
||||
@@ -170,7 +176,7 @@ export function downloadSelectedExcel<T extends Record<string, unknown>>({
|
||||
}: ExcelDownloadOptions<T> & {
|
||||
selectedIds: string[];
|
||||
idField?: keyof T | string;
|
||||
}): void {
|
||||
}): Promise<void> {
|
||||
const selectedData = data.filter((item) => {
|
||||
const id = getNestedValue(item as Record<string, unknown>, idField as string);
|
||||
return selectedIds.includes(String(id));
|
||||
@@ -181,7 +187,7 @@ export function downloadSelectedExcel<T extends Record<string, unknown>>({
|
||||
return;
|
||||
}
|
||||
|
||||
downloadExcel({
|
||||
await downloadExcel({
|
||||
...options,
|
||||
data: selectedData,
|
||||
});
|
||||
@@ -244,14 +250,15 @@ export interface TemplateDownloadOptions {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function downloadExcelTemplate({
|
||||
export async function downloadExcelTemplate({
|
||||
columns,
|
||||
filename = '업로드_양식',
|
||||
sheetName = 'Sheet1',
|
||||
includeSampleRow = true,
|
||||
includeGuideRow = true,
|
||||
}: TemplateDownloadOptions): void {
|
||||
}: TemplateDownloadOptions): Promise<void> {
|
||||
try {
|
||||
const XLSX = await loadXLSX();
|
||||
const wsData: (string | number | boolean)[][] = [];
|
||||
|
||||
// 1. 헤더 행 (필수 표시 포함)
|
||||
@@ -384,6 +391,7 @@ export async function parseExcelFile<T = Record<string, unknown>>(
|
||||
}
|
||||
): Promise<ExcelParseResult<T>> {
|
||||
const { columns, skipRows = 1, sheetIndex = 0 } = options;
|
||||
const XLSX = await loadXLSX();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
Reference in New Issue
Block a user