Merge branch 'gbpark-node' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node
This commit is contained in:
@@ -492,24 +492,22 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
return `${height}px`; // 숫자면 px 추가
|
||||
};
|
||||
|
||||
const componentStyle: React.CSSProperties = isPreview
|
||||
const componentStyle: React.CSSProperties = isDesignMode
|
||||
? {
|
||||
// 반응형 모드: position relative, 그리드 컨테이너가 제공하는 크기 사용
|
||||
position: "relative",
|
||||
width: "100%", // 🆕 부모 컨테이너 너비에 맞춤
|
||||
height: getHeightValue(),
|
||||
border: "1px solid #e5e7eb",
|
||||
}
|
||||
: {
|
||||
// 디자이너 모드: position absolute
|
||||
position: "absolute",
|
||||
left: `${component.style?.positionX || 0}px`,
|
||||
top: `${component.style?.positionY || 0}px`,
|
||||
width: "100%", // 🆕 부모 컨테이너 너비에 맞춤 (그리드 기반)
|
||||
width: "100%",
|
||||
height: getHeightValue(),
|
||||
zIndex: component.style?.positionZ || 1,
|
||||
cursor: isDesignMode ? "pointer" : "default",
|
||||
cursor: "pointer",
|
||||
border: isSelected ? "2px solid #3b82f6" : "1px solid #e5e7eb",
|
||||
}
|
||||
: {
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
border: "1px solid #e5e7eb",
|
||||
};
|
||||
|
||||
// 계층 구조 빌드 함수 (트리 구조 유지)
|
||||
@@ -2491,13 +2489,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={{
|
||||
...(isPreview
|
||||
? {
|
||||
position: "relative",
|
||||
height: `${component.style?.height || 600}px`,
|
||||
border: "1px solid #e5e7eb",
|
||||
}
|
||||
: componentStyle),
|
||||
...componentStyle,
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
@@ -2511,7 +2503,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
>
|
||||
{/* 좌측 패널 */}
|
||||
<div
|
||||
style={{ width: `${leftWidth}%`, minWidth: isPreview ? "0" : `${minLeftWidth}px`, height: "100%" }}
|
||||
style={{ width: `${leftWidth}%`, minWidth: isDesignMode ? `${minLeftWidth}px` : "0", height: "100%" }}
|
||||
className="border-border flex flex-shrink-0 flex-col border-r"
|
||||
>
|
||||
<Card className="flex flex-col border-0 shadow-none" style={{ height: "100%" }}>
|
||||
@@ -2558,21 +2550,21 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
{isDesignMode ? (
|
||||
// 디자인 모드: 샘플 테이블
|
||||
<div className="overflow-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="bg-gray-50">
|
||||
<table className="min-w-full divide-y divide-border">
|
||||
<thead className="bg-muted">
|
||||
<tr>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">컬럼 1</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">컬럼 2</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase">컬럼 3</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium text-muted-foreground uppercase">컬럼 1</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium text-muted-foreground uppercase">컬럼 2</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium text-muted-foreground uppercase">컬럼 3</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 bg-white">
|
||||
<tr className="cursor-pointer hover:bg-gray-50">
|
||||
<tbody className="divide-y divide-border bg-white">
|
||||
<tr className="cursor-pointer hover:bg-muted">
|
||||
<td className="px-3 py-2 text-sm whitespace-nowrap">데이터 1-1</td>
|
||||
<td className="px-3 py-2 text-sm whitespace-nowrap">데이터 1-2</td>
|
||||
<td className="px-3 py-2 text-sm whitespace-nowrap">데이터 1-3</td>
|
||||
</tr>
|
||||
<tr className="cursor-pointer hover:bg-gray-50">
|
||||
<tr className="cursor-pointer hover:bg-muted">
|
||||
<td className="px-3 py-2 text-sm whitespace-nowrap">데이터 2-1</td>
|
||||
<td className="px-3 py-2 text-sm whitespace-nowrap">데이터 2-2</td>
|
||||
<td className="px-3 py-2 text-sm whitespace-nowrap">데이터 2-3</td>
|
||||
@@ -2638,16 +2630,16 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
<div className="overflow-auto">
|
||||
{groupedLeftData.map((group, groupIdx) => (
|
||||
<div key={groupIdx} className="mb-4">
|
||||
<div className="bg-gray-100 px-3 py-2 text-sm font-semibold">
|
||||
<div className="bg-muted px-3 py-2 text-sm font-semibold">
|
||||
{group.groupKey} ({group.count}개)
|
||||
</div>
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="bg-gray-50">
|
||||
<table className="min-w-full divide-y divide-border">
|
||||
<thead className="bg-muted">
|
||||
<tr>
|
||||
{columnsToShow.map((col, idx) => (
|
||||
<th
|
||||
key={idx}
|
||||
className="px-3 py-2 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
|
||||
className="px-3 py-2 text-left text-xs font-medium tracking-wider text-muted-foreground uppercase"
|
||||
style={{
|
||||
width: col.width ? `${col.width}px` : "auto",
|
||||
textAlign: col.align || "left",
|
||||
@@ -2658,7 +2650,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 bg-white">
|
||||
<tbody className="divide-y divide-border bg-white">
|
||||
{group.items.map((item, idx) => {
|
||||
const sourceColumn = componentConfig.leftPanel?.itemAddConfig?.sourceColumn || "id";
|
||||
const itemId = item[sourceColumn] || item.id || item.ID;
|
||||
@@ -2677,7 +2669,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
{columnsToShow.map((col, colIdx) => (
|
||||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-gray-900"
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
@@ -2702,13 +2694,13 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
// 🔧 일반 테이블 렌더링 (그룹화 없음)
|
||||
return (
|
||||
<div className="overflow-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="sticky top-0 z-10 bg-gray-50">
|
||||
<table className="min-w-full divide-y divide-border">
|
||||
<thead className="sticky top-0 z-10 bg-muted">
|
||||
<tr>
|
||||
{columnsToShow.map((col, idx) => (
|
||||
<th
|
||||
key={idx}
|
||||
className="px-3 py-2 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
|
||||
className="px-3 py-2 text-left text-xs font-medium tracking-wider text-muted-foreground uppercase"
|
||||
style={{
|
||||
width: col.width ? `${col.width}px` : "auto",
|
||||
minWidth: "80px",
|
||||
@@ -2720,7 +2712,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 bg-white">
|
||||
<tbody className="divide-y divide-border bg-white">
|
||||
{filteredData.map((item, idx) => {
|
||||
const sourceColumn = componentConfig.leftPanel?.itemAddConfig?.sourceColumn || "id";
|
||||
const itemId = item[sourceColumn] || item.id || item.ID;
|
||||
@@ -2739,7 +2731,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
{columnsToShow.map((col, colIdx) => (
|
||||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-gray-900"
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
@@ -2898,9 +2890,9 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
{hasChildren ? (
|
||||
<div className="flex-shrink-0">
|
||||
{isExpanded ? (
|
||||
<ChevronDown className="h-4 w-4 text-gray-500" />
|
||||
<ChevronDown className="h-4 w-4 text-muted-foreground" />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4 text-gray-500" />
|
||||
<ChevronRight className="h-4 w-4 text-muted-foreground" />
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
@@ -2924,10 +2916,10 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
e.stopPropagation();
|
||||
handleEditClick("left", item);
|
||||
}}
|
||||
className="rounded p-1 transition-colors hover:bg-gray-200"
|
||||
className="rounded p-1 transition-colors hover:bg-muted/80"
|
||||
title="수정"
|
||||
>
|
||||
<Pencil className="h-4 w-4 text-gray-600" />
|
||||
<Pencil className="h-4 w-4 text-muted-foreground" />
|
||||
</button>
|
||||
|
||||
{/* 삭제 버튼 */}
|
||||
@@ -2936,10 +2928,10 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
e.stopPropagation();
|
||||
handleDeleteClick("left", item);
|
||||
}}
|
||||
className="rounded p-1 transition-colors hover:bg-red-100"
|
||||
className="rounded p-1 transition-colors hover:bg-destructive/10"
|
||||
title="삭제"
|
||||
>
|
||||
<Trash2 className="h-4 w-4 text-red-600" />
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
</button>
|
||||
|
||||
{/* 항목별 추가 버튼 */}
|
||||
@@ -2949,10 +2941,10 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
e.stopPropagation();
|
||||
handleItemAddClick(item);
|
||||
}}
|
||||
className="rounded p-1 transition-colors hover:bg-gray-200"
|
||||
className="rounded p-1 transition-colors hover:bg-muted/80"
|
||||
title="하위 항목 추가"
|
||||
>
|
||||
<Plus className="h-4 w-4 text-gray-600" />
|
||||
<Plus className="h-4 w-4 text-muted-foreground" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -3004,7 +2996,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
|
||||
{/* 우측 패널 */}
|
||||
<div
|
||||
style={{ width: `${100 - leftWidth}%`, minWidth: isPreview ? "0" : `${minRightWidth}px`, height: "100%" }}
|
||||
style={{ width: `${100 - leftWidth}%`, minWidth: isDesignMode ? `${minRightWidth}px` : "0", height: "100%" }}
|
||||
className="flex flex-shrink-0 flex-col"
|
||||
>
|
||||
<Card className="flex flex-col border-0 shadow-none" style={{ height: "100%" }}>
|
||||
@@ -3185,7 +3177,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-7 w-7 p-0 text-red-500 hover:text-red-600"
|
||||
className="h-7 w-7 p-0 text-destructive hover:text-destructive"
|
||||
onClick={() => handleDeleteClick("right", item)}
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
@@ -3262,7 +3254,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-7 w-7 p-0 text-red-500 hover:text-red-600"
|
||||
className="h-7 w-7 p-0 text-destructive hover:text-destructive"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteClick("right", item);
|
||||
@@ -3273,9 +3265,9 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
)}
|
||||
{detailColumns.length > 0 &&
|
||||
(isExpanded ? (
|
||||
<ChevronUp className="h-4 w-4 text-gray-400" />
|
||||
<ChevronUp className="h-4 w-4 text-muted-foreground/70" />
|
||||
) : (
|
||||
<ChevronDown className="h-4 w-4 text-gray-400" />
|
||||
<ChevronDown className="h-4 w-4 text-muted-foreground/70" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -3388,13 +3380,13 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
)}
|
||||
</div>
|
||||
<div className="overflow-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="sticky top-0 z-10 bg-gray-50">
|
||||
<table className="min-w-full divide-y divide-border">
|
||||
<thead className="sticky top-0 z-10 bg-muted">
|
||||
<tr>
|
||||
{columnsToShow.map((col, idx) => (
|
||||
<th
|
||||
key={idx}
|
||||
className="px-3 py-2 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
|
||||
className="px-3 py-2 text-left text-xs font-medium tracking-wider text-muted-foreground uppercase"
|
||||
style={{
|
||||
width: col.width ? `${col.width}px` : "auto",
|
||||
textAlign: col.align || "left",
|
||||
@@ -3407,13 +3399,13 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
{!isDesignMode &&
|
||||
((componentConfig.rightPanel?.editButton?.enabled ?? true) ||
|
||||
(componentConfig.rightPanel?.deleteButton?.enabled ?? true)) && (
|
||||
<th className="px-3 py-2 text-right text-xs font-medium text-gray-500 uppercase">
|
||||
<th className="px-3 py-2 text-right text-xs font-medium text-muted-foreground uppercase">
|
||||
작업
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 bg-white">
|
||||
<tbody className="divide-y divide-border bg-white">
|
||||
{filteredData.map((item, idx) => {
|
||||
const itemId = item.id || item.ID;
|
||||
|
||||
@@ -3422,7 +3414,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
{columnsToShow.map((col, colIdx) => (
|
||||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-gray-900"
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
@@ -3461,10 +3453,10 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
e.stopPropagation();
|
||||
handleDeleteClick("right", item);
|
||||
}}
|
||||
className="rounded p-1 transition-colors hover:bg-red-100"
|
||||
className="rounded p-1 transition-colors hover:bg-destructive/10"
|
||||
title={componentConfig.rightPanel?.deleteButton?.buttonLabel || "삭제"}
|
||||
>
|
||||
<Trash2 className="h-4 w-4 text-red-600" />
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -3594,16 +3586,16 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
e.stopPropagation();
|
||||
handleDeleteClick("right", item);
|
||||
}}
|
||||
className="rounded p-1 transition-colors hover:bg-red-100"
|
||||
className="rounded p-1 transition-colors hover:bg-destructive/10"
|
||||
title={componentConfig.rightPanel?.deleteButton?.buttonLabel || "삭제"}
|
||||
>
|
||||
<Trash2 className="h-4 w-4 text-red-600" />
|
||||
<Trash2 className="h-4 w-4 text-destructive" />
|
||||
</button>
|
||||
)}
|
||||
{/* 확장/접기 버튼 */}
|
||||
<button
|
||||
onClick={() => toggleRightItemExpansion(itemId)}
|
||||
className="rounded p-1 transition-colors hover:bg-gray-200"
|
||||
className="rounded p-1 transition-colors hover:bg-muted/80"
|
||||
>
|
||||
{isExpanded ? (
|
||||
<ChevronUp className="text-muted-foreground h-5 w-5" />
|
||||
@@ -3808,7 +3800,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
||||
<div key={index}>
|
||||
<Label htmlFor={col.name} className="text-xs sm:text-sm">
|
||||
{col.label} {col.required && <span className="text-destructive">*</span>}
|
||||
{isPreFilled && <span className="ml-2 text-[10px] text-blue-600">(자동 설정됨)</span>}
|
||||
{isPreFilled && <span className="ml-2 text-[10px] text-primary">(자동 설정됨)</span>}
|
||||
</Label>
|
||||
<Input
|
||||
id={col.name}
|
||||
|
||||
Reference in New Issue
Block a user