ERP-node/frontend/components/unified/config-panels/UnifiedListConfigPanel.tsx

247 lines
8.1 KiB
TypeScript

"use client";
/**
* UnifiedList 설정 패널
* 통합 목록 컴포넌트의 세부 설정을 관리합니다.
*/
import React from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { Checkbox } from "@/components/ui/checkbox";
import { Button } from "@/components/ui/button";
import { Plus, Trash2 } from "lucide-react";
interface UnifiedListConfigPanelProps {
config: Record<string, any>;
onChange: (config: Record<string, any>) => void;
}
export const UnifiedListConfigPanel: React.FC<UnifiedListConfigPanelProps> = ({
config,
onChange,
}) => {
// 설정 업데이트 핸들러
const updateConfig = (field: string, value: any) => {
onChange({ ...config, [field]: value });
};
// 컬럼 관리
const columns = config.columns || [];
const addColumn = () => {
const newColumns = [...columns, { key: "", title: "", width: "" }];
updateConfig("columns", newColumns);
};
const updateColumn = (index: number, field: string, value: string) => {
const newColumns = [...columns];
newColumns[index] = { ...newColumns[index], [field]: value };
updateConfig("columns", newColumns);
};
const removeColumn = (index: number) => {
const newColumns = columns.filter((_: any, i: number) => i !== index);
updateConfig("columns", newColumns);
};
return (
<div className="space-y-4">
{/* 뷰 모드 */}
<div className="space-y-2">
<Label className="text-xs font-medium"> </Label>
<Select
value={config.viewMode || "table"}
onValueChange={(value) => updateConfig("viewMode", value)}
>
<SelectTrigger className="h-8 text-xs">
<SelectValue placeholder="방식 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="table"></SelectItem>
<SelectItem value="card"></SelectItem>
<SelectItem value="kanban"></SelectItem>
<SelectItem value="list"></SelectItem>
</SelectContent>
</Select>
</div>
<Separator />
{/* 데이터 소스 */}
<div className="space-y-2">
<Label className="text-xs font-medium"> </Label>
<Select
value={config.source || "static"}
onValueChange={(value) => updateConfig("source", value)}
>
<SelectTrigger className="h-8 text-xs">
<SelectValue placeholder="소스 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="static"> </SelectItem>
<SelectItem value="db"></SelectItem>
<SelectItem value="api">API</SelectItem>
</SelectContent>
</Select>
</div>
{/* DB 설정 */}
{config.source === "db" && (
<div className="space-y-2">
<Label className="text-xs font-medium"></Label>
<Input
value={config.tableName || ""}
onChange={(e) => updateConfig("tableName", e.target.value)}
placeholder="테이블명"
className="h-8 text-xs"
/>
</div>
)}
{/* API 설정 */}
{config.source === "api" && (
<div className="space-y-2">
<Label className="text-xs font-medium">API </Label>
<Input
value={config.apiEndpoint || ""}
onChange={(e) => updateConfig("apiEndpoint", e.target.value)}
placeholder="/api/list"
className="h-8 text-xs"
/>
</div>
)}
<Separator />
{/* 컬럼 설정 */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label className="text-xs font-medium"> </Label>
<Button
type="button"
variant="ghost"
size="sm"
onClick={addColumn}
className="h-6 px-2 text-xs"
>
<Plus className="h-3 w-3 mr-1" />
</Button>
</div>
<div className="space-y-2 max-h-40 overflow-y-auto">
{columns.map((column: any, index: number) => (
<div key={index} className="flex items-center gap-2">
<Input
value={column.key || ""}
onChange={(e) => updateColumn(index, "key", e.target.value)}
placeholder="키"
className="h-7 text-xs flex-1"
/>
<Input
value={column.title || ""}
onChange={(e) => updateColumn(index, "title", e.target.value)}
placeholder="제목"
className="h-7 text-xs flex-1"
/>
<Input
value={column.width || ""}
onChange={(e) => updateColumn(index, "width", e.target.value)}
placeholder="너비"
className="h-7 text-xs w-16"
/>
<Button
type="button"
variant="ghost"
size="sm"
onClick={() => removeColumn(index)}
className="h-7 w-7 p-0 text-destructive"
>
<Trash2 className="h-3 w-3" />
</Button>
</div>
))}
{columns.length === 0 && (
<p className="text-xs text-muted-foreground text-center py-2">
</p>
)}
</div>
</div>
<Separator />
{/* 기능 옵션 */}
<div className="space-y-3">
<Label className="text-xs font-medium"> </Label>
<div className="flex items-center space-x-2">
<Checkbox
id="sortable"
checked={config.sortable !== false}
onCheckedChange={(checked) => updateConfig("sortable", checked)}
/>
<label htmlFor="sortable" className="text-xs"> </label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="pagination"
checked={config.pagination !== false}
onCheckedChange={(checked) => updateConfig("pagination", checked)}
/>
<label htmlFor="pagination" className="text-xs"></label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="searchable"
checked={config.searchable || false}
onCheckedChange={(checked) => updateConfig("searchable", checked)}
/>
<label htmlFor="searchable" className="text-xs"> </label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="editable"
checked={config.editable || false}
onCheckedChange={(checked) => updateConfig("editable", checked)}
/>
<label htmlFor="editable" className="text-xs"> </label>
</div>
</div>
{/* 페이지 크기 */}
{config.pagination !== false && (
<div className="space-y-2">
<Label className="text-xs font-medium"> </Label>
<Select
value={String(config.pageSize || 10)}
onValueChange={(value) => updateConfig("pageSize", Number(value))}
>
<SelectTrigger className="h-8 text-xs">
<SelectValue placeholder="선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="5">5</SelectItem>
<SelectItem value="10">10</SelectItem>
<SelectItem value="20">20</SelectItem>
<SelectItem value="50">50</SelectItem>
<SelectItem value="100">100</SelectItem>
</SelectContent>
</Select>
</div>
)}
</div>
);
};
UnifiedListConfigPanel.displayName = "UnifiedListConfigPanel";
export default UnifiedListConfigPanel;