ERP-node/frontend/components/screen/panels/DetailSettingsPanel.tsx

255 lines
8.1 KiB
TypeScript

"use client";
import React from "react";
import { Settings } from "lucide-react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import {
ComponentData,
WidgetComponent,
WebTypeConfig,
DateTypeConfig,
NumberTypeConfig,
SelectTypeConfig,
TextTypeConfig,
TextareaTypeConfig,
CheckboxTypeConfig,
RadioTypeConfig,
FileTypeConfig,
CodeTypeConfig,
EntityTypeConfig,
ButtonTypeConfig,
} from "@/types/screen";
import { DateTypeConfigPanel } from "./webtype-configs/DateTypeConfigPanel";
import { NumberTypeConfigPanel } from "./webtype-configs/NumberTypeConfigPanel";
import { SelectTypeConfigPanel } from "./webtype-configs/SelectTypeConfigPanel";
import { TextTypeConfigPanel } from "./webtype-configs/TextTypeConfigPanel";
import { TextareaTypeConfigPanel } from "./webtype-configs/TextareaTypeConfigPanel";
import { CheckboxTypeConfigPanel } from "./webtype-configs/CheckboxTypeConfigPanel";
import { RadioTypeConfigPanel } from "./webtype-configs/RadioTypeConfigPanel";
import { FileTypeConfigPanel } from "./webtype-configs/FileTypeConfigPanel";
import { CodeTypeConfigPanel } from "./webtype-configs/CodeTypeConfigPanel";
import { EntityTypeConfigPanel } from "./webtype-configs/EntityTypeConfigPanel";
import { ButtonConfigPanel } from "./ButtonConfigPanel";
interface DetailSettingsPanelProps {
selectedComponent?: ComponentData;
onUpdateProperty: (componentId: string, path: string, value: any) => void;
}
export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({ selectedComponent, onUpdateProperty }) => {
// 입력 가능한 웹타입들 정의
const inputableWebTypes = [
"text",
"number",
"decimal",
"date",
"datetime",
"select",
"dropdown",
"textarea",
"email",
"tel",
"code",
"entity",
"file",
"checkbox",
"radio",
];
// 웹타입별 상세 설정 렌더링 함수
const renderWebTypeConfig = React.useCallback(
(widget: WidgetComponent) => {
const currentConfig = widget.webTypeConfig || {};
console.log("🎨 DetailSettingsPanel renderWebTypeConfig 호출:", {
componentId: widget.id,
widgetType: widget.widgetType,
currentConfig,
configExists: !!currentConfig,
configKeys: Object.keys(currentConfig),
configStringified: JSON.stringify(currentConfig),
widgetWebTypeConfig: widget.webTypeConfig,
widgetWebTypeConfigExists: !!widget.webTypeConfig,
timestamp: new Date().toISOString(),
});
const handleConfigChange = (newConfig: WebTypeConfig) => {
console.log("🔧 WebTypeConfig 업데이트:", {
widgetType: widget.widgetType,
oldConfig: currentConfig,
newConfig,
componentId: widget.id,
isEqual: JSON.stringify(currentConfig) === JSON.stringify(newConfig),
});
// 강제 새 객체 생성으로 React 변경 감지 보장
const freshConfig = { ...newConfig };
onUpdateProperty(widget.id, "webTypeConfig", freshConfig);
};
switch (widget.widgetType) {
case "date":
case "datetime":
return (
<DateTypeConfigPanel
key={`date-config-${widget.id}`}
config={currentConfig as DateTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "number":
case "decimal":
return (
<NumberTypeConfigPanel
key={`${widget.id}-number`}
config={currentConfig as NumberTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "select":
case "dropdown":
return (
<SelectTypeConfigPanel
key={`${widget.id}-select`}
config={currentConfig as SelectTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "text":
case "email":
case "tel":
return (
<TextTypeConfigPanel
key={`${widget.id}-text`}
config={currentConfig as TextTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "textarea":
return (
<TextareaTypeConfigPanel
key={`${widget.id}-textarea`}
config={currentConfig as TextareaTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "checkbox":
case "boolean":
return (
<CheckboxTypeConfigPanel
key={`${widget.id}-checkbox`}
config={currentConfig as CheckboxTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "radio":
return (
<RadioTypeConfigPanel
key={`${widget.id}-radio`}
config={currentConfig as RadioTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "file":
return (
<FileTypeConfigPanel
key={`${widget.id}-file`}
config={currentConfig as FileTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "code":
return (
<CodeTypeConfigPanel
key={`${widget.id}-code`}
config={currentConfig as CodeTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "entity":
return (
<EntityTypeConfigPanel
key={`${widget.id}-entity`}
config={currentConfig as EntityTypeConfig}
onConfigChange={handleConfigChange}
/>
);
case "button":
return (
<ButtonConfigPanel
key={`${widget.id}-button`}
component={widget}
onUpdateComponent={(updates) => {
Object.entries(updates).forEach(([key, value]) => {
onUpdateProperty(widget.id, key, value);
});
}}
/>
);
default:
return <div className="text-sm text-gray-500 italic"> .</div>;
}
},
[onUpdateProperty],
);
if (!selectedComponent) {
return (
<div className="flex h-full flex-col items-center justify-center p-6 text-center">
<Settings className="mb-4 h-12 w-12 text-gray-400" />
<h3 className="mb-2 text-lg font-medium text-gray-900"> </h3>
<p className="text-sm text-gray-500"> .</p>
</div>
);
}
if (selectedComponent.type !== "widget") {
return (
<div className="flex h-full flex-col items-center justify-center p-6 text-center">
<Settings className="mb-4 h-12 w-12 text-gray-400" />
<h3 className="mb-2 text-lg font-medium text-gray-900"> </h3>
<p className="text-sm text-gray-500">
.
<br />
: {selectedComponent.type}
</p>
</div>
);
}
const widget = selectedComponent as WidgetComponent;
return (
<div className="flex h-full flex-col">
{/* 헤더 */}
<div className="border-b border-gray-200 p-4">
<div className="flex items-center space-x-2">
<Settings className="h-4 w-4 text-gray-600" />
<h3 className="font-medium text-gray-900"> </h3>
</div>
<div className="mt-2 flex items-center space-x-2">
<span className="text-sm text-gray-600">:</span>
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">{widget.widgetType}</span>
</div>
<div className="mt-1 text-xs text-gray-500">: {widget.columnName}</div>
</div>
{/* 상세 설정 영역 */}
<div className="flex-1 overflow-y-auto p-4">{renderWebTypeConfig(widget)}</div>
</div>
);
};
export default DetailSettingsPanel;