ERP-node/frontend/lib/registry/components/customer-item-mapping/CustomerItemMappingConfigPa...

398 lines
13 KiB
TypeScript

"use client";
import React, { useState, useEffect } from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { CustomerItemMappingConfig } from "./types";
import { tableTypeApi } from "@/lib/api/screen";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Plus, X } from "lucide-react";
export interface CustomerItemMappingConfigPanelProps {
config: CustomerItemMappingConfig;
onChange: (config: CustomerItemMappingConfig) => void;
onConfigChange?: (config: CustomerItemMappingConfig) => void;
screenTableName?: string;
tableColumns?: any[];
tables?: any[];
allTables?: any[];
onTableChange?: (tableName: string) => void;
menuObjid?: number;
}
export const CustomerItemMappingConfigPanel: React.FC<
CustomerItemMappingConfigPanelProps
> = ({
config,
onChange,
onConfigChange,
screenTableName,
tableColumns: propTableColumns,
tables: propTables,
allTables,
onTableChange: propOnTableChange,
menuObjid,
}) => {
// onChange와 onConfigChange를 통합
const handleChange = (newConfig: CustomerItemMappingConfig) => {
onChange?.(newConfig);
onConfigChange?.(newConfig);
};
const [tables, setTables] = useState<any[]>([]);
const [availableColumns, setAvailableColumns] = useState<any[]>([]);
// 테이블 목록 로드
useEffect(() => {
const loadTables = async () => {
try {
const tableList = await tableTypeApi.getTables();
setTables(tableList);
} catch (error) {
console.error("테이블 목록 로드 실패:", error);
}
};
loadTables();
}, []);
// 선택된 테이블의 컬럼 목록 로드
useEffect(() => {
if (config.selectedTable) {
const loadColumns = async () => {
try {
const columns = await tableTypeApi.getColumns(config.selectedTable!);
setAvailableColumns(columns);
} catch (error) {
console.error("컬럼 목록 로드 실패:", error);
}
};
loadColumns();
}
}, [config.selectedTable]);
const handleTableChange = (tableName: string) => {
const newConfig = {
...config,
selectedTable: tableName,
columns: [], // 테이블 변경 시 컬럼 초기화
};
handleChange(newConfig);
propOnTableChange?.(tableName);
};
const handleAddColumn = (columnName: string) => {
if (!config.columns.includes(columnName)) {
handleChange({
...config,
columns: [...config.columns, columnName],
});
}
};
const handleRemoveColumn = (columnName: string) => {
handleChange({
...config,
columns: config.columns.filter((col) => col !== columnName),
});
};
return (
<div className="space-y-6 p-4">
{/* 테이블 선택 */}
<div className="space-y-2">
<Label> </Label>
<Select value={config.selectedTable} onValueChange={handleTableChange}>
<SelectTrigger>
<SelectValue placeholder="테이블을 선택하세요" />
</SelectTrigger>
<SelectContent>
{tables.map((table) => (
<SelectItem key={table.tableName} value={table.tableName}>
{table.displayName || table.tableName}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* 컬럼 설정 */}
<div className="space-y-2">
<Label> </Label>
<div className="space-y-2">
{/* 선택된 컬럼 목록 */}
{config.columns.length > 0 && (
<div className="border-border space-y-1 rounded border p-2">
{config.columns.map((col, index) => (
<div
key={col}
className="bg-muted flex items-center justify-between rounded px-2 py-1"
>
<span className="text-sm">{col}</span>
<Button
variant="ghost"
size="sm"
onClick={() => handleRemoveColumn(col)}
className="h-6 w-6 p-0"
>
<X className="h-3 w-3" />
</Button>
</div>
))}
</div>
)}
{/* 컬럼 추가 */}
{availableColumns.length > 0 && (
<Select onValueChange={handleAddColumn}>
<SelectTrigger>
<SelectValue placeholder="컬럼 추가" />
</SelectTrigger>
<SelectContent>
{availableColumns
.filter((col) => !config.columns.includes(col.columnName))
.map((col) => (
<SelectItem key={col.columnName} value={col.columnName}>
{col.displayName || col.columnName}
</SelectItem>
))}
</SelectContent>
</Select>
)}
</div>
</div>
{/* 체크박스 설정 */}
<div className="space-y-3">
<Label> </Label>
<div className="space-y-2">
<label className="flex items-center gap-2">
<Checkbox
checked={config.checkbox?.enabled !== false}
onCheckedChange={(checked) =>
handleChange({
...config,
checkbox: {
...config.checkbox,
enabled: checked as boolean,
},
})
}
/>
<span className="text-sm"> </span>
</label>
<label className="flex items-center gap-2">
<Checkbox
checked={config.checkbox?.selectAll !== false}
onCheckedChange={(checked) =>
handleChange({
...config,
checkbox: {
...config.checkbox,
selectAll: checked as boolean,
},
})
}
/>
<span className="text-sm"> </span>
</label>
<label className="flex items-center gap-2">
<Checkbox
checked={config.checkbox?.multiple !== false}
onCheckedChange={(checked) =>
handleChange({
...config,
checkbox: {
...config.checkbox,
multiple: checked as boolean,
},
})
}
/>
<span className="text-sm"> </span>
</label>
</div>
</div>
{/* 헤더 설정 */}
<div className="space-y-3">
<Label> </Label>
<label className="flex items-center gap-2">
<Checkbox
checked={config.showCompanyName === true}
onCheckedChange={(checked) =>
handleChange({
...config,
showCompanyName: checked as boolean,
})
}
/>
<span className="text-sm font-medium"> </span>
</label>
{config.showCompanyName && availableColumns.length > 0 && (
<div className="space-y-2 pl-6">
<Label className="text-xs"> </Label>
<Select
value={config.companyNameColumn || ""}
onValueChange={(value) =>
handleChange({
...config,
companyNameColumn: value,
})
}
>
<SelectTrigger className="h-8 text-xs">
<SelectValue placeholder="컬럼 선택" />
</SelectTrigger>
<SelectContent>
{availableColumns.map((col) => (
<SelectItem key={col.columnName} value={col.columnName} className="text-xs">
{col.displayName || col.columnName}
</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-muted-foreground text-[10px]">
</p>
</div>
)}
</div>
{/* 검색 영역 설정 */}
<div className="space-y-3">
<Label>/ </Label>
<label className="flex items-center gap-2">
<Checkbox
checked={config.showSearchArea === true}
onCheckedChange={(checked) =>
handleChange({
...config,
showSearchArea: checked as boolean,
})
}
/>
<span className="text-sm font-medium">
/
</span>
</label>
{config.showSearchArea && (
<div className="space-y-3 pl-6">
<div className="space-y-2">
<Label className="text-xs"> </Label>
<Input
value={config.searchPlaceholder || ""}
onChange={(e) =>
handleChange({
...config,
searchPlaceholder: e.target.value,
})
}
placeholder="품목코드, 품목명, 규격 검색"
className="h-8 text-xs"
/>
</div>
{/* 카테고리 필터 설정 */}
<div className="space-y-2">
<label className="flex items-center gap-2">
<Checkbox
checked={config.enableCategoryFilter === true}
onCheckedChange={(checked) =>
handleChange({
...config,
enableCategoryFilter: checked as boolean,
})
}
/>
<span className="text-xs font-medium"> </span>
</label>
{config.enableCategoryFilter && (
<div className="space-y-2 pl-6">
<Label className="text-xs"> ( )</Label>
<Input
value={(config.categories || []).join(", ")}
onChange={(e) =>
handleChange({
...config,
categories: e.target.value.split(",").map((c) => c.trim()).filter(Boolean),
})
}
placeholder="전체, 원자재, 반도체, 완제품"
className="h-8 text-xs"
/>
<p className="text-muted-foreground text-[10px]">
: 전체, , ,
</p>
{availableColumns.length > 0 && (
<>
<Label className="text-xs"> </Label>
<Select
value={config.categoryColumn || ""}
onValueChange={(value) =>
handleChange({
...config,
categoryColumn: value,
})
}
>
<SelectTrigger className="h-8 text-xs">
<SelectValue placeholder="컬럼 선택" />
</SelectTrigger>
<SelectContent>
{availableColumns.map((col) => (
<SelectItem key={col.columnName} value={col.columnName} className="text-xs">
{col.displayName || col.columnName}
</SelectItem>
))}
</SelectContent>
</Select>
</>
)}
</div>
)}
</div>
</div>
)}
</div>
{/* 빈 데이터 메시지 */}
<div className="space-y-2">
<Label> </Label>
<Input
value={config.emptyMessage || ""}
onChange={(e) =>
handleChange({ ...config, emptyMessage: e.target.value })
}
placeholder="데이터가 없습니다"
/>
</div>
<div className="space-y-2">
<Label> </Label>
<Input
value={config.emptyDescription || ""}
onChange={(e) =>
handleChange({ ...config, emptyDescription: e.target.value })
}
placeholder="품목 데이터가 추가되면 여기에 표시됩니다"
/>
</div>
</div>
);
};