183 lines
5.1 KiB
TypeScript
183 lines
5.1 KiB
TypeScript
"use client";
|
|
|
|
import { AutoRegisteringLayoutRenderer } from "../AutoRegisteringLayoutRenderer";
|
|
import { CardLayoutDefinition } from "./index";
|
|
import { CardLayoutLayout } from "./CardLayoutLayout";
|
|
import React, { useState, useEffect } from "react";
|
|
import { tableTypeApi } from "@/lib/api/screen";
|
|
|
|
/**
|
|
* 카드 레이아웃 렌더러 컴포넌트
|
|
*/
|
|
const CardLayoutRendererComponent: React.FC<any> = (props) => {
|
|
const { layout, children, onUpdateLayout, onSelectComponent, isDesignMode } = props;
|
|
const [tableData, setTableData] = useState<any[]>([]);
|
|
const [tableColumns, setTableColumns] = useState<any[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
// 테이블 데이터 로딩
|
|
useEffect(() => {
|
|
const loadTableData = async () => {
|
|
// 디자인 모드에서는 테이블 데이터를 로드하지 않음
|
|
if (isDesignMode) {
|
|
return;
|
|
}
|
|
|
|
// 카드 설정에서 테이블명 확인 (여러 소스에서 시도)
|
|
const tableName =
|
|
layout?.tableName ||
|
|
layout?.screenTableName ||
|
|
props?.tableName ||
|
|
props?.selectedScreen?.tableName ||
|
|
"company_mng"; // 임시 하드코딩 (테스트용)
|
|
|
|
if (!tableName) {
|
|
console.log("📋 카드 레이아웃: 테이블명이 설정되지 않음", {
|
|
layoutTableName: layout?.tableName,
|
|
screenTableName: layout?.screenTableName,
|
|
propsTableName: props?.tableName,
|
|
selectedScreenTableName: props?.selectedScreen?.tableName,
|
|
});
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setLoading(true);
|
|
console.log(`📋 카드 레이아웃: ${tableName} 테이블 데이터 로딩 시작`);
|
|
|
|
// 테이블 데이터와 컬럼 정보를 병렬로 로드
|
|
const [dataResponse, columnsResponse] = await Promise.all([
|
|
tableTypeApi.getTableData(tableName, {
|
|
page: 1,
|
|
size: 50, // 카드 레이아웃용으로 적당한 개수
|
|
}),
|
|
tableTypeApi.getColumns(tableName),
|
|
]);
|
|
|
|
console.log(`📋 카드 레이아웃: ${tableName} 데이터 로딩 완료`, {
|
|
total: dataResponse.total,
|
|
dataLength: dataResponse.data.length,
|
|
columnsLength: columnsResponse.length,
|
|
sampleData: dataResponse.data.slice(0, 2),
|
|
sampleColumns: columnsResponse.slice(0, 3),
|
|
});
|
|
|
|
setTableData(dataResponse.data);
|
|
setTableColumns(columnsResponse);
|
|
} catch (error) {
|
|
console.error(`❌ 카드 레이아웃: ${tableName} 데이터 로딩 실패`, error);
|
|
setTableData([]);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
loadTableData();
|
|
}, [layout?.tableName, isDesignMode]);
|
|
|
|
return (
|
|
<CardLayoutLayout
|
|
layout={layout}
|
|
children={children}
|
|
onUpdateLayout={onUpdateLayout}
|
|
onSelectComponent={onSelectComponent}
|
|
isDesignMode={isDesignMode}
|
|
tableData={tableData}
|
|
tableColumns={tableColumns}
|
|
/>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* 카드 레이아웃 렌더러
|
|
* AutoRegisteringLayoutRenderer를 상속받아 자동 등록 기능 제공
|
|
*/
|
|
export class CardLayoutRenderer extends AutoRegisteringLayoutRenderer {
|
|
/**
|
|
* 레이아웃 정의 (자동 등록용)
|
|
*/
|
|
static layoutDefinition = CardLayoutDefinition;
|
|
|
|
/**
|
|
* 카드 레이아웃 렌더링
|
|
*/
|
|
render(): React.ReactElement {
|
|
return <CardLayoutRendererComponent {...this.props} />;
|
|
}
|
|
|
|
/**
|
|
* 카드 컨테이너 스타일 계산
|
|
*/
|
|
getCardContainerStyle(): React.CSSProperties {
|
|
const cardConfig = this.props.layout.layoutConfig?.cardLayout || {
|
|
columns: 3,
|
|
gap: 16,
|
|
};
|
|
|
|
return {
|
|
display: "grid",
|
|
gridTemplateColumns: `repeat(${cardConfig.columns}, 1fr)`,
|
|
gridTemplateRows: "repeat(2, 300px)",
|
|
gap: `${cardConfig.gap}px`,
|
|
padding: "16px",
|
|
width: "100%",
|
|
height: "100%",
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 개별 카드 스타일 계산
|
|
*/
|
|
getCardStyle(zoneId: string): React.CSSProperties {
|
|
const baseStyle: React.CSSProperties = {
|
|
backgroundColor: "white",
|
|
border: "1px solid #e5e7eb",
|
|
borderRadius: "8px",
|
|
padding: "16px",
|
|
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1)",
|
|
transition: "all 0.2s ease-in-out",
|
|
overflow: "hidden",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
position: "relative",
|
|
minHeight: "200px",
|
|
};
|
|
|
|
// 디자인 모드에서 추가 스타일
|
|
if (this.props.isDesignMode) {
|
|
return {
|
|
...baseStyle,
|
|
cursor: "pointer",
|
|
borderColor: "#d1d5db",
|
|
};
|
|
}
|
|
|
|
return baseStyle;
|
|
}
|
|
|
|
/**
|
|
* 카드 호버 효과 계산
|
|
*/
|
|
getCardHoverStyle(): React.CSSProperties {
|
|
return {
|
|
borderColor: "#3b82f6",
|
|
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
|
|
transform: "translateY(-1px)",
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 그리드 위치 계산
|
|
*/
|
|
getGridPosition(index: number): { row: number; column: number } {
|
|
const columns = this.props.layout.layoutConfig?.cardLayout?.columns || 3;
|
|
return {
|
|
row: Math.floor(index / columns),
|
|
column: index % columns,
|
|
};
|
|
}
|
|
}
|
|
|
|
// 자동 등록 실행
|
|
CardLayoutRenderer.registerSelf();
|