177 lines
5.3 KiB
TypeScript
177 lines
5.3 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* UnifiedList
|
|
*
|
|
* 통합 리스트 컴포넌트
|
|
* 기존 TableListComponent를 래핑하여 동일한 기능 제공
|
|
*/
|
|
|
|
import React, { forwardRef, useMemo } from "react";
|
|
import { TableListComponent } from "@/lib/registry/components/table-list/TableListComponent";
|
|
import { UnifiedListProps } from "@/types/unified-components";
|
|
|
|
/**
|
|
* 메인 UnifiedList 컴포넌트
|
|
* 기존 TableListComponent의 모든 기능을 그대로 사용
|
|
*/
|
|
export const UnifiedList = forwardRef<HTMLDivElement, UnifiedListProps>((props, ref) => {
|
|
const { id, style, size, config: configProp, onRowSelect } = props;
|
|
|
|
// config가 없으면 기본값 사용
|
|
const config = configProp || {
|
|
viewMode: "table" as const,
|
|
source: "static" as const,
|
|
columns: [],
|
|
};
|
|
|
|
// 테이블명 추출 (여러 가능한 경로에서 시도)
|
|
const tableName = config.dataSource?.table || (config as any).tableName || (props as any).tableName;
|
|
|
|
// columns 형식 변환 (UnifiedListConfigPanel 형식 -> TableListComponent 형식)
|
|
const tableColumns = useMemo(
|
|
() =>
|
|
(config.columns || []).map((col: any, index: number) => ({
|
|
columnName: col.key || col.field || "",
|
|
displayName: col.title || col.header || col.key || col.field || "",
|
|
width: col.width ? parseInt(col.width, 10) : undefined,
|
|
visible: true,
|
|
sortable: true,
|
|
searchable: true,
|
|
align: "left" as const,
|
|
order: index,
|
|
isEntityJoin: col.isJoinColumn || false,
|
|
thousandSeparator: col.thousandSeparator !== false, // 천단위 구분자 (기본: true)
|
|
})),
|
|
[config.columns],
|
|
);
|
|
|
|
// TableListComponent에 전달할 component 객체 생성
|
|
const componentObj = useMemo(
|
|
() => ({
|
|
id: id || "unified-list",
|
|
type: "table-list",
|
|
config: {
|
|
selectedTable: tableName,
|
|
tableName: tableName,
|
|
columns: tableColumns,
|
|
displayMode: config.viewMode === "card" ? "card" : "table",
|
|
cardConfig: {
|
|
idColumn: config.cardConfig?.titleColumn || tableColumns[0]?.columnName || "id",
|
|
titleColumn: config.cardConfig?.titleColumn || tableColumns[0]?.columnName || "",
|
|
subtitleColumn: config.cardConfig?.subtitleColumn || undefined,
|
|
descriptionColumn: config.cardConfig?.descriptionColumn || undefined,
|
|
imageColumn: config.cardConfig?.imageColumn || undefined,
|
|
cardsPerRow: config.cardConfig?.cardsPerRow || 3,
|
|
cardSpacing: 16,
|
|
showActions: false,
|
|
},
|
|
showHeader: config.viewMode !== "card", // 카드 모드에서는 테이블 헤더 숨김
|
|
showFooter: false,
|
|
checkbox: {
|
|
enabled: true, // 항상 체크박스 활성화 (modalDataStore에 자동 저장)
|
|
position: "left" as const,
|
|
showHeader: true,
|
|
},
|
|
height: "auto" as const, // auto로 변경하여 스크롤 가능하게
|
|
autoWidth: true,
|
|
stickyHeader: true,
|
|
autoLoad: true,
|
|
horizontalScroll: {
|
|
enabled: true,
|
|
minColumnWidth: 100,
|
|
maxColumnWidth: 300,
|
|
},
|
|
pagination: {
|
|
enabled: config.pagination !== false,
|
|
pageSize: config.pageSize || 10,
|
|
position: "bottom" as const,
|
|
showPageSize: true, // 사용자가 실제 화면에서 페이지 크기 변경 가능
|
|
pageSizeOptions: [5, 10, 20, 50, 100],
|
|
},
|
|
filter: {
|
|
enabled: false, // 필터 비활성화 (필요시 활성화)
|
|
position: "top" as const,
|
|
searchPlaceholder: "검색...",
|
|
},
|
|
actions: {
|
|
enabled: false,
|
|
items: [],
|
|
},
|
|
tableStyle: {
|
|
striped: false,
|
|
bordered: true,
|
|
hover: true,
|
|
compact: false,
|
|
},
|
|
toolbar: {
|
|
showRefresh: true,
|
|
showExport: false,
|
|
showColumnToggle: false,
|
|
},
|
|
},
|
|
style: {},
|
|
gridColumns: 1,
|
|
}),
|
|
[
|
|
id,
|
|
tableName,
|
|
tableColumns,
|
|
config.viewMode,
|
|
config.pagination,
|
|
config.pageSize,
|
|
config.cardConfig,
|
|
onRowSelect,
|
|
],
|
|
);
|
|
|
|
// 테이블이 없으면 안내 메시지
|
|
if (!tableName) {
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
id={id}
|
|
className="bg-muted/20 flex items-center justify-center rounded-lg border p-8"
|
|
style={{
|
|
width: size?.width || style?.width || "100%",
|
|
height: size?.height || style?.height || 400,
|
|
}}
|
|
>
|
|
<p className="text-muted-foreground text-sm">테이블이 설정되지 않았습니다.</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
id={id}
|
|
className="flex flex-col overflow-auto"
|
|
style={{
|
|
width: size?.width || style?.width || "100%",
|
|
height: size?.height || style?.height || 400,
|
|
}}
|
|
>
|
|
<TableListComponent
|
|
component={componentObj}
|
|
tableName={tableName}
|
|
style={{
|
|
width: "100%",
|
|
minHeight: "100%",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
}}
|
|
onSelectedRowsChange={
|
|
onRowSelect
|
|
? (_, selectedData) => {
|
|
onRowSelect(selectedData);
|
|
}
|
|
: undefined
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
UnifiedList.displayName = "UnifiedList";
|