182 lines
4.8 KiB
TypeScript
182 lines
4.8 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 || (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,
|
|
})),
|
|
[config.columns],
|
|
);
|
|
|
|
// 디버깅: config.cardConfig 확인
|
|
console.log("📋 UnifiedList config.cardConfig:", config.cardConfig);
|
|
|
|
// 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: tableColumns[0]?.columnName || "id",
|
|
titleColumn: tableColumns[0]?.columnName || "",
|
|
subtitleColumn: undefined,
|
|
descriptionColumn: undefined,
|
|
imageColumn: undefined,
|
|
cardsPerRow: 3,
|
|
cardSpacing: 16,
|
|
showActions: false,
|
|
...config.cardConfig,
|
|
},
|
|
showHeader: true,
|
|
showFooter: false,
|
|
checkbox: {
|
|
enabled: !!onRowSelect,
|
|
position: "left" as const,
|
|
showHeader: true,
|
|
},
|
|
height: "fixed" as const,
|
|
autoWidth: true,
|
|
stickyHeader: true,
|
|
autoLoad: true,
|
|
horizontalScroll: {
|
|
enabled: true,
|
|
minColumnWidth: 100,
|
|
maxColumnWidth: 300,
|
|
},
|
|
pagination: {
|
|
enabled: config.pageable !== false,
|
|
pageSize: config.pageSize || 20,
|
|
position: "bottom" as const,
|
|
showPageSize: true,
|
|
pageSizeOptions: [10, 20, 50, 100],
|
|
},
|
|
filter: {
|
|
enabled: config.searchable !== 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.pageable,
|
|
config.searchable,
|
|
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-hidden"
|
|
style={{
|
|
width: size?.width || style?.width || "100%",
|
|
height: size?.height || style?.height || 400,
|
|
}}
|
|
>
|
|
<TableListComponent
|
|
component={componentObj}
|
|
tableName={tableName}
|
|
style={{
|
|
width: "100%",
|
|
height: "100%",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
overflow: "hidden",
|
|
}}
|
|
onSelectedRowsChange={
|
|
onRowSelect
|
|
? (_, selectedData) => {
|
|
onRowSelect(selectedData);
|
|
}
|
|
: undefined
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
UnifiedList.displayName = "UnifiedList";
|