ERP-node/frontend/lib/registry/components/rack-structure/RackStructureConfigPanel.tsx

288 lines
9.3 KiB
TypeScript
Raw Normal View History

2025-12-08 15:15:44 +09:00
"use client";
import React, { useState, useEffect } from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { RackStructureComponentConfig, FieldMapping } from "./types";
interface RackStructureConfigPanelProps {
config: RackStructureComponentConfig;
onChange: (config: RackStructureComponentConfig) => void;
// 화면관리에서 전달하는 테이블 컬럼 정보
tables?: Array<{
tableName: string;
tableLabel?: string;
columns: Array<{
columnName: string;
columnLabel?: string;
dataType?: string;
}>;
}>;
}
export const RackStructureConfigPanel: React.FC<RackStructureConfigPanelProps> = ({
config,
onChange,
tables = [],
}) => {
// 사용 가능한 컬럼 목록 추출
const [availableColumns, setAvailableColumns] = useState<
Array<{ value: string; label: string }>
>([]);
useEffect(() => {
// 모든 테이블의 컬럼을 플랫하게 추출
const columns: Array<{ value: string; label: string }> = [];
tables.forEach((table) => {
table.columns.forEach((col) => {
columns.push({
value: col.columnName,
label: col.columnLabel || col.columnName,
});
});
});
setAvailableColumns(columns);
}, [tables]);
const handleChange = (key: keyof RackStructureComponentConfig, value: any) => {
onChange({ ...config, [key]: value });
};
const handleFieldMappingChange = (field: keyof FieldMapping, value: string) => {
const currentMapping = config.fieldMapping || {};
onChange({
...config,
fieldMapping: {
...currentMapping,
[field]: value === "__none__" ? undefined : value,
},
});
};
const fieldMapping = config.fieldMapping || {};
return (
<div className="space-y-4">
{/* 필드 매핑 섹션 */}
<div className="space-y-3">
<div className="text-sm font-medium text-gray-700"> </div>
<p className="text-xs text-gray-500">
</p>
{/* 창고 코드 필드 */}
<div>
<Label className="text-xs"> </Label>
<Select
value={fieldMapping.warehouseCodeField || "__none__"}
onValueChange={(v) => handleFieldMappingChange("warehouseCodeField", v)}
>
<SelectTrigger className="h-8">
<SelectValue placeholder="필드 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__"> </SelectItem>
{availableColumns.map((col) => (
<SelectItem key={col.value} value={col.value}>
{col.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* 창고명 필드 */}
<div>
<Label className="text-xs"> </Label>
<Select
value={fieldMapping.warehouseNameField || "__none__"}
onValueChange={(v) => handleFieldMappingChange("warehouseNameField", v)}
>
<SelectTrigger className="h-8">
<SelectValue placeholder="필드 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__"> </SelectItem>
{availableColumns.map((col) => (
<SelectItem key={col.value} value={col.value}>
{col.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* 층 필드 */}
<div>
<Label className="text-xs"> </Label>
<Select
value={fieldMapping.floorField || "__none__"}
onValueChange={(v) => handleFieldMappingChange("floorField", v)}
>
<SelectTrigger className="h-8">
<SelectValue placeholder="필드 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__"> </SelectItem>
{availableColumns.map((col) => (
<SelectItem key={col.value} value={col.value}>
{col.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* 구역 필드 */}
<div>
<Label className="text-xs"> </Label>
<Select
value={fieldMapping.zoneField || "__none__"}
onValueChange={(v) => handleFieldMappingChange("zoneField", v)}
>
<SelectTrigger className="h-8">
<SelectValue placeholder="필드 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__"> </SelectItem>
{availableColumns.map((col) => (
<SelectItem key={col.value} value={col.value}>
{col.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* 위치 유형 필드 */}
<div>
<Label className="text-xs"> </Label>
<Select
value={fieldMapping.locationTypeField || "__none__"}
onValueChange={(v) => handleFieldMappingChange("locationTypeField", v)}
>
<SelectTrigger className="h-8">
<SelectValue placeholder="필드 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__"> </SelectItem>
{availableColumns.map((col) => (
<SelectItem key={col.value} value={col.value}>
{col.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* 사용 여부 필드 */}
<div>
<Label className="text-xs"> </Label>
<Select
value={fieldMapping.statusField || "__none__"}
onValueChange={(v) => handleFieldMappingChange("statusField", v)}
>
<SelectTrigger className="h-8">
<SelectValue placeholder="필드 선택" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none__"> </SelectItem>
{availableColumns.map((col) => (
<SelectItem key={col.value} value={col.value}>
{col.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
{/* 제한 설정 */}
<div className="space-y-3 border-t pt-3">
<div className="text-sm font-medium text-gray-700"> </div>
<div>
<Label className="text-xs"> </Label>
<Input
type="number"
min={1}
max={20}
value={config.maxConditions || 10}
onChange={(e) => handleChange("maxConditions", parseInt(e.target.value) || 10)}
className="h-8"
/>
</div>
<div>
<Label className="text-xs"> </Label>
<Input
type="number"
min={1}
max={999}
value={config.maxRows || 99}
onChange={(e) => handleChange("maxRows", parseInt(e.target.value) || 99)}
className="h-8"
/>
</div>
<div>
<Label className="text-xs"> </Label>
<Input
type="number"
min={1}
max={99}
value={config.maxLevels || 20}
onChange={(e) => handleChange("maxLevels", parseInt(e.target.value) || 20)}
className="h-8"
/>
</div>
</div>
{/* UI 설정 */}
<div className="space-y-3 border-t pt-3">
<div className="text-sm font-medium text-gray-700">UI </div>
<div className="flex items-center justify-between">
<Label className="text-xs">릿 </Label>
<Switch
checked={config.showTemplates ?? true}
onCheckedChange={(checked) => handleChange("showTemplates", checked)}
/>
</div>
<div className="flex items-center justify-between">
<Label className="text-xs"> </Label>
<Switch
checked={config.showPreview ?? true}
onCheckedChange={(checked) => handleChange("showPreview", checked)}
/>
</div>
<div className="flex items-center justify-between">
<Label className="text-xs"> </Label>
<Switch
checked={config.showStatistics ?? true}
onCheckedChange={(checked) => handleChange("showStatistics", checked)}
/>
</div>
<div className="flex items-center justify-between">
<Label className="text-xs"> </Label>
<Switch
checked={config.readonly ?? false}
onCheckedChange={(checked) => handleChange("readonly", checked)}
/>
</div>
</div>
</div>
);
};