템플릿관리, 컴포넌트 관리
This commit is contained in:
@@ -15,7 +15,7 @@ import {
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
// Card 컴포넌트 제거 - 외부 박스 없이 직접 렌더링
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import {
|
||||
@@ -1683,13 +1683,13 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className={cn("flex h-full flex-col", className)} style={{ ...style, minHeight: "680px" }}>
|
||||
<div className={cn("flex h-full flex-col", className)} style={{ ...style, minHeight: "680px" }}>
|
||||
{/* 헤더 */}
|
||||
<CardHeader className="pb-3">
|
||||
<div className="p-6 pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Database className="text-muted-foreground h-4 w-4" />
|
||||
<CardTitle className="text-lg">{component.title || component.label}</CardTitle>
|
||||
<h3 className="text-lg font-semibold">{component.title || component.label}</h3>
|
||||
{loading && (
|
||||
<Badge variant="secondary" className="flex items-center gap-1">
|
||||
<Loader2 className="h-3 w-3 animate-spin" />
|
||||
@@ -1753,10 +1753,10 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
<>
|
||||
<Separator className="my-2" />
|
||||
<div className="space-y-3">
|
||||
<CardDescription className="flex items-center gap-2">
|
||||
<div className="text-muted-foreground flex items-center gap-2 text-sm">
|
||||
<Search className="h-3 w-3" />
|
||||
검색 필터
|
||||
</CardDescription>
|
||||
</div>
|
||||
<div
|
||||
className="grid gap-3"
|
||||
style={{
|
||||
@@ -1775,10 +1775,10 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</CardHeader>
|
||||
</div>
|
||||
|
||||
{/* 테이블 내용 */}
|
||||
<CardContent className="flex-1 p-0">
|
||||
<div className="flex-1 p-0">
|
||||
<div className="flex h-full flex-col">
|
||||
{visibleColumns.length > 0 ? (
|
||||
<>
|
||||
@@ -1803,26 +1803,14 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
{column.label}
|
||||
</TableHead>
|
||||
))}
|
||||
{/* 기본 파일 컬럼은 가상 파일 컬럼이 있으면 완전히 숨김 */}
|
||||
{!visibleColumns.some((col) => col.widgetType === "file") && (
|
||||
<TableHead className="w-16 px-4 text-center">
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
<Folder className="h-4 w-4" />
|
||||
<span className="text-xs">파일</span>
|
||||
</div>
|
||||
</TableHead>
|
||||
)}
|
||||
{/* 자동 파일 컬럼 표시 제거됨 - 명시적으로 추가된 파일 컬럼만 표시 */}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{loading ? (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={
|
||||
visibleColumns.length +
|
||||
(component.enableDelete ? 1 : 0) +
|
||||
(!visibleColumns.some((col) => col.widgetType === "file") ? 1 : 0)
|
||||
}
|
||||
colSpan={visibleColumns.length + (component.enableDelete ? 1 : 0)}
|
||||
className="h-32 text-center"
|
||||
>
|
||||
<div className="text-muted-foreground flex items-center justify-center gap-2">
|
||||
@@ -1848,51 +1836,13 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
{formatCellValue(row[column.columnName], column, row)}
|
||||
</TableCell>
|
||||
))}
|
||||
{/* 기본 파일 셀은 가상 파일 컬럼이 있으면 완전히 숨김 */}
|
||||
{!visibleColumns.some((col) => col.widgetType === "file") && (
|
||||
<TableCell className="w-16 px-4 text-center">
|
||||
{(() => {
|
||||
const primaryKeyField = Object.keys(row)[0];
|
||||
const recordId = row[primaryKeyField];
|
||||
const fileStatus = fileStatusMap[recordId];
|
||||
const hasFiles = fileStatus?.hasFiles || false;
|
||||
const fileCount = fileStatus?.fileCount || 0;
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-8 w-8 p-0 hover:bg-blue-50"
|
||||
onClick={() => handleFileIconClick(row)}
|
||||
title={hasFiles ? `${fileCount}개 파일 보기` : "파일 업로드"}
|
||||
>
|
||||
{hasFiles ? (
|
||||
<div className="relative">
|
||||
<FolderOpen className="h-4 w-4 text-blue-600" />
|
||||
{fileCount > 0 && (
|
||||
<div className="absolute -top-1 -right-1 flex h-3 w-3 items-center justify-center rounded-full bg-blue-600 text-[10px] text-white">
|
||||
{fileCount > 9 ? "9+" : fileCount}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Folder className="h-4 w-4 text-gray-400" />
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
})()}
|
||||
</TableCell>
|
||||
)}
|
||||
{/* 자동 파일 셀 표시 제거됨 - 명시적으로 추가된 파일 컬럼만 표시 */}
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={
|
||||
visibleColumns.length +
|
||||
(component.enableDelete ? 1 : 0) +
|
||||
(!visibleColumns.some((col) => col.widgetType === "file") ? 1 : 0)
|
||||
}
|
||||
colSpan={visibleColumns.length + (component.enableDelete ? 1 : 0)}
|
||||
className="h-32 text-center"
|
||||
>
|
||||
<div className="text-muted-foreground flex flex-col items-center gap-2">
|
||||
@@ -1980,7 +1930,7 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</div>
|
||||
|
||||
{/* 데이터 추가 모달 */}
|
||||
<Dialog open={showAddModal} onOpenChange={handleAddModalClose}>
|
||||
@@ -2502,6 +2452,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user