247 lines
8.3 KiB
TypeScript
247 lines
8.3 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* 메일 수신자 선택 컴포넌트 설정 패널
|
|
* 화면관리에서 컴포넌트 설정 시 사용
|
|
*/
|
|
|
|
import React, { useEffect, useState, useCallback } from "react";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Switch } from "@/components/ui/switch";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import type { MailRecipientSelectorConfig } from "./types";
|
|
|
|
interface MailRecipientSelectorConfigPanelProps {
|
|
config: MailRecipientSelectorConfig;
|
|
onConfigChange: (config: MailRecipientSelectorConfig) => void;
|
|
}
|
|
|
|
export const MailRecipientSelectorConfigPanel: React.FC<
|
|
MailRecipientSelectorConfigPanelProps
|
|
> = ({ config, onConfigChange }) => {
|
|
// 로컬 상태
|
|
const [localConfig, setLocalConfig] = useState<MailRecipientSelectorConfig>({
|
|
toFieldName: "mailTo",
|
|
ccFieldName: "mailCc",
|
|
showCc: true,
|
|
showInternalSelector: true,
|
|
showExternalInput: true,
|
|
toLabel: "수신자",
|
|
ccLabel: "참조(CC)",
|
|
required: true,
|
|
...config,
|
|
});
|
|
|
|
// config prop 변경 시 로컬 상태 동기화
|
|
useEffect(() => {
|
|
setLocalConfig({
|
|
toFieldName: "mailTo",
|
|
ccFieldName: "mailCc",
|
|
showCc: true,
|
|
showInternalSelector: true,
|
|
showExternalInput: true,
|
|
toLabel: "수신자",
|
|
ccLabel: "참조(CC)",
|
|
required: true,
|
|
...config,
|
|
});
|
|
}, [config]);
|
|
|
|
// 설정 업데이트 함수
|
|
const updateConfig = useCallback(
|
|
(key: keyof MailRecipientSelectorConfig, value: any) => {
|
|
const newConfig = { ...localConfig, [key]: value };
|
|
setLocalConfig(newConfig);
|
|
onConfigChange(newConfig);
|
|
},
|
|
[localConfig, onConfigChange]
|
|
);
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* 필드명 설정 */}
|
|
<Card>
|
|
<CardHeader className="py-3">
|
|
<CardTitle className="text-sm">필드명 설정</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<div className="space-y-1">
|
|
<Label className="text-xs">수신자 필드명</Label>
|
|
<Input
|
|
value={localConfig.toFieldName || "mailTo"}
|
|
onChange={(e) => updateConfig("toFieldName", e.target.value)}
|
|
placeholder="mailTo"
|
|
className="h-8 text-sm"
|
|
/>
|
|
<p className="text-[10px] text-gray-500">
|
|
formData에 저장될 수신자 필드명 (제어에서 {`{{mailTo}}`}로 사용)
|
|
</p>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<Label className="text-xs">참조 필드명</Label>
|
|
<Input
|
|
value={localConfig.ccFieldName || "mailCc"}
|
|
onChange={(e) => updateConfig("ccFieldName", e.target.value)}
|
|
placeholder="mailCc"
|
|
className="h-8 text-sm"
|
|
/>
|
|
<p className="text-[10px] text-gray-500">
|
|
formData에 저장될 참조 필드명 (제어에서 {`{{mailCc}}`}로 사용)
|
|
</p>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 표시 옵션 */}
|
|
<Card>
|
|
<CardHeader className="py-3">
|
|
<CardTitle className="text-sm">표시 옵션</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<Label className="text-xs">참조(CC) 필드 표시</Label>
|
|
<p className="text-[10px] text-gray-500">참조 수신자 입력 필드 표시</p>
|
|
</div>
|
|
<Switch
|
|
checked={localConfig.showCc !== false}
|
|
onCheckedChange={(checked) => updateConfig("showCc", checked)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<Label className="text-xs">내부 인원 선택</Label>
|
|
<p className="text-[10px] text-gray-500">회사 내부 사용자 선택 기능</p>
|
|
</div>
|
|
<Switch
|
|
checked={localConfig.showInternalSelector !== false}
|
|
onCheckedChange={(checked) =>
|
|
updateConfig("showInternalSelector", checked)
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<Label className="text-xs">외부 이메일 입력</Label>
|
|
<p className="text-[10px] text-gray-500">외부 이메일 직접 입력 기능</p>
|
|
</div>
|
|
<Switch
|
|
checked={localConfig.showExternalInput !== false}
|
|
onCheckedChange={(checked) =>
|
|
updateConfig("showExternalInput", checked)
|
|
}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<Label className="text-xs">필수 입력</Label>
|
|
<p className="text-[10px] text-gray-500">수신자 필수 입력 여부</p>
|
|
</div>
|
|
<Switch
|
|
checked={localConfig.required !== false}
|
|
onCheckedChange={(checked) => updateConfig("required", checked)}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 라벨 설정 */}
|
|
<Card>
|
|
<CardHeader className="py-3">
|
|
<CardTitle className="text-sm">라벨 설정</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<div className="space-y-1">
|
|
<Label className="text-xs">수신자 라벨</Label>
|
|
<Input
|
|
value={localConfig.toLabel || "수신자"}
|
|
onChange={(e) => updateConfig("toLabel", e.target.value)}
|
|
placeholder="수신자"
|
|
className="h-8 text-sm"
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<Label className="text-xs">참조 라벨</Label>
|
|
<Input
|
|
value={localConfig.ccLabel || "참조(CC)"}
|
|
onChange={(e) => updateConfig("ccLabel", e.target.value)}
|
|
placeholder="참조(CC)"
|
|
className="h-8 text-sm"
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 제한 설정 */}
|
|
<Card>
|
|
<CardHeader className="py-3">
|
|
<CardTitle className="text-sm">제한 설정</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<div className="space-y-1">
|
|
<Label className="text-xs">최대 수신자 수</Label>
|
|
<Input
|
|
type="number"
|
|
value={localConfig.maxRecipients || ""}
|
|
onChange={(e) =>
|
|
updateConfig(
|
|
"maxRecipients",
|
|
e.target.value ? parseInt(e.target.value) : undefined
|
|
)
|
|
}
|
|
placeholder="무제한"
|
|
className="h-8 text-sm"
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<Label className="text-xs">최대 참조 수신자 수</Label>
|
|
<Input
|
|
type="number"
|
|
value={localConfig.maxCcRecipients || ""}
|
|
onChange={(e) =>
|
|
updateConfig(
|
|
"maxCcRecipients",
|
|
e.target.value ? parseInt(e.target.value) : undefined
|
|
)
|
|
}
|
|
placeholder="무제한"
|
|
className="h-8 text-sm"
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* 사용 안내 */}
|
|
<Card className="bg-blue-50">
|
|
<CardContent className="p-3">
|
|
<div className="text-xs text-blue-700">
|
|
<p className="font-medium mb-1">사용 방법</p>
|
|
<ol className="list-decimal list-inside space-y-1">
|
|
<li>이 컴포넌트를 모달 화면에 배치합니다.</li>
|
|
<li>
|
|
제어관리의 메일 발송 노드에서 수신자를{" "}
|
|
<code className="bg-blue-100 px-1 rounded">{`{{mailTo}}`}</code>로 설정합니다.
|
|
</li>
|
|
<li>
|
|
참조는{" "}
|
|
<code className="bg-blue-100 px-1 rounded">{`{{mailCc}}`}</code>로 설정합니다.
|
|
</li>
|
|
<li>부모 화면에서 선택한 데이터는 별도 변수로 접근 가능합니다.</li>
|
|
</ol>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MailRecipientSelectorConfigPanel;
|
|
|