카드 디스플레이 옵션 설정
This commit is contained in:
@@ -42,7 +42,14 @@ export interface ComponentRenderer {
|
||||
// 테이블 선택된 행 정보 (다중 선택 액션용)
|
||||
selectedRows?: any[];
|
||||
selectedRowsData?: any[];
|
||||
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[], sortBy?: string, sortOrder?: "asc" | "desc", columnOrder?: string[], tableDisplayData?: any[]) => void;
|
||||
onSelectedRowsChange?: (
|
||||
selectedRows: any[],
|
||||
selectedRowsData: any[],
|
||||
sortBy?: string,
|
||||
sortOrder?: "asc" | "desc",
|
||||
columnOrder?: string[],
|
||||
tableDisplayData?: any[],
|
||||
) => void;
|
||||
// 테이블 정렬 정보 (엑셀 다운로드용)
|
||||
sortBy?: string;
|
||||
sortOrder?: "asc" | "desc";
|
||||
@@ -126,7 +133,14 @@ export interface DynamicComponentRendererProps {
|
||||
// 🆕 비활성화할 필드 목록 (EditModal → 각 컴포넌트)
|
||||
disabledFields?: string[];
|
||||
selectedRowsData?: any[];
|
||||
onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[], sortBy?: string, sortOrder?: "asc" | "desc", columnOrder?: string[], tableDisplayData?: any[]) => void;
|
||||
onSelectedRowsChange?: (
|
||||
selectedRows: any[],
|
||||
selectedRowsData: any[],
|
||||
sortBy?: string,
|
||||
sortOrder?: "asc" | "desc",
|
||||
columnOrder?: string[],
|
||||
tableDisplayData?: any[],
|
||||
) => void;
|
||||
// 테이블 정렬 정보 (엑셀 다운로드용)
|
||||
sortBy?: string;
|
||||
sortOrder?: "asc" | "desc";
|
||||
@@ -146,7 +160,7 @@ export interface DynamicComponentRendererProps {
|
||||
// 모달 내에서 렌더링 여부
|
||||
isInModal?: boolean;
|
||||
// 탭 관련 정보 (탭 내부의 컴포넌트에서 사용)
|
||||
parentTabId?: string; // 부모 탭 ID
|
||||
parentTabId?: string; // 부모 탭 ID
|
||||
parentTabsComponentId?: string; // 부모 탭 컴포넌트 ID
|
||||
// 🆕 조건부 비활성화 상태
|
||||
conditionalDisabled?: boolean;
|
||||
@@ -172,7 +186,7 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
const config = (component as any).componentConfig || {};
|
||||
const fieldName = (component as any).columnName || component.id;
|
||||
const currentValue = props.formData?.[fieldName];
|
||||
|
||||
|
||||
const handleChange = (value: any) => {
|
||||
if (props.onFormDataChange) {
|
||||
props.onFormDataChange(fieldName, value);
|
||||
@@ -259,6 +273,9 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
);
|
||||
|
||||
case "unified-list":
|
||||
// 데이터 소스: config.data > props.tableDisplayData > []
|
||||
const listData = config.data?.length > 0 ? config.data : props.tableDisplayData || [];
|
||||
|
||||
return (
|
||||
<UnifiedList
|
||||
unifiedType="UnifiedList"
|
||||
@@ -271,8 +288,28 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
pagination: config.pagination,
|
||||
searchable: config.searchable,
|
||||
editable: config.editable,
|
||||
pageable: config.pageable,
|
||||
pageSize: config.pageSize,
|
||||
cardConfig: config.cardConfig,
|
||||
dataSource: {
|
||||
table: config.dataSource?.table || props.tableName,
|
||||
},
|
||||
}}
|
||||
data={config.data || []}
|
||||
data={listData}
|
||||
selectedRows={props.selectedRowsData || []}
|
||||
onRowSelect={
|
||||
props.onSelectedRowsChange
|
||||
? (rows) =>
|
||||
props.onSelectedRowsChange?.(
|
||||
rows.map((r: any) => r.id || r.objid),
|
||||
rows,
|
||||
props.sortBy,
|
||||
props.sortOrder,
|
||||
undefined,
|
||||
props.tableDisplayData,
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -372,17 +409,22 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
const webType = (component as any).componentConfig?.webType;
|
||||
const tableName = (component as any).tableName;
|
||||
const columnName = (component as any).columnName;
|
||||
|
||||
|
||||
// 카테고리 셀렉트: webType이 "category"이고 tableName과 columnName이 있는 경우만
|
||||
// ⚠️ 단, componentType이 "select-basic"인 경우는 ComponentRegistry로 처리 (다중선택 등 고급 기능 지원)
|
||||
if ((inputType === "category" || webType === "category") && tableName && columnName && componentType === "select-basic") {
|
||||
if (
|
||||
(inputType === "category" || webType === "category") &&
|
||||
tableName &&
|
||||
columnName &&
|
||||
componentType === "select-basic"
|
||||
) {
|
||||
// select-basic은 ComponentRegistry에서 처리하도록 아래로 통과
|
||||
} else if ((inputType === "category" || webType === "category") && tableName && columnName) {
|
||||
try {
|
||||
const { CategorySelectComponent } = require("@/lib/registry/components/category-select/CategorySelectComponent");
|
||||
const fieldName = columnName || component.id;
|
||||
const currentValue = props.formData?.[fieldName] || "";
|
||||
|
||||
|
||||
const handleChange = (value: any) => {
|
||||
if (props.onFormDataChange) {
|
||||
props.onFormDataChange(fieldName, value);
|
||||
@@ -496,7 +538,7 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
|
||||
// 컴포넌트의 columnName에 해당하는 formData 값 추출
|
||||
const fieldName = (component as any).columnName || component.id;
|
||||
|
||||
|
||||
// modal-repeater-table은 배열 데이터를 다루므로 빈 배열로 초기화
|
||||
let currentValue;
|
||||
if (componentType === "modal-repeater-table" || componentType === "repeat-screen-modal") {
|
||||
@@ -505,7 +547,7 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
} else {
|
||||
currentValue = formData?.[fieldName] || "";
|
||||
}
|
||||
|
||||
|
||||
// onChange 핸들러 - 컴포넌트 타입에 따라 다르게 처리
|
||||
const handleChange = (value: any) => {
|
||||
// autocomplete-search-input, entity-search-input은 자체적으로 onFormDataChange를 호출하므로 중복 저장 방지
|
||||
@@ -551,10 +593,11 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
};
|
||||
|
||||
// 🆕 엔티티 검색 컴포넌트는 componentConfig.tableName을 사용해야 함 (화면 테이블이 아닌 검색 대상 테이블)
|
||||
const useConfigTableName = componentType === "entity-search-input" ||
|
||||
componentType === "autocomplete-search-input" ||
|
||||
componentType === "modal-repeater-table";
|
||||
|
||||
const useConfigTableName =
|
||||
componentType === "entity-search-input" ||
|
||||
componentType === "autocomplete-search-input" ||
|
||||
componentType === "modal-repeater-table";
|
||||
|
||||
const rendererProps = {
|
||||
component,
|
||||
isSelected,
|
||||
@@ -578,7 +621,7 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
onFormDataChange,
|
||||
onChange: handleChange, // 개선된 onChange 핸들러 전달
|
||||
// 🆕 엔티티 검색 컴포넌트는 componentConfig.tableName 유지, 그 외는 화면 테이블명 사용
|
||||
tableName: useConfigTableName ? (component.componentConfig?.tableName || tableName) : tableName,
|
||||
tableName: useConfigTableName ? component.componentConfig?.tableName || tableName : tableName,
|
||||
menuId, // 🆕 메뉴 ID
|
||||
menuObjid, // 🆕 메뉴 OBJID (메뉴 스코프)
|
||||
selectedScreen, // 🆕 화면 정보
|
||||
@@ -677,10 +720,10 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
||||
|
||||
// 폴백 렌더링 - 기본 플레이스홀더
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center rounded border-2 border-dashed border-border bg-muted p-4">
|
||||
<div className="border-border bg-muted flex h-full w-full items-center justify-center rounded border-2 border-dashed p-4">
|
||||
<div className="text-center">
|
||||
<div className="mb-2 text-sm font-medium text-muted-foreground">{component.label || component.id}</div>
|
||||
<div className="text-xs text-muted-foreground/70">미구현 컴포넌트: {componentType}</div>
|
||||
<div className="text-muted-foreground mb-2 text-sm font-medium">{component.label || component.id}</div>
|
||||
<div className="text-muted-foreground/70 text-xs">미구현 컴포넌트: {componentType}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user