Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into feature/screen-management
This commit is contained in:
@@ -304,7 +304,24 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
||||
};
|
||||
|
||||
// 저장 버튼 클릭 시 - UPDATE 액션 실행
|
||||
const handleSave = async () => {
|
||||
const handleSave = async (saveData?: any) => {
|
||||
// universal-form-modal 등에서 자체 저장 완료 후 호출된 경우 스킵
|
||||
if (saveData?._saveCompleted) {
|
||||
console.log("[EditModal] 자체 저장 완료된 컴포넌트에서 호출됨 - 저장 스킵");
|
||||
|
||||
// 부모 컴포넌트의 onSave 콜백 실행 (테이블 새로고침)
|
||||
if (modalState.onSave) {
|
||||
try {
|
||||
modalState.onSave();
|
||||
} catch (callbackError) {
|
||||
console.error("onSave 콜백 에러:", callbackError);
|
||||
}
|
||||
}
|
||||
|
||||
handleClose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!screenData?.screenInfo?.tableName) {
|
||||
toast.error("테이블 정보가 없습니다.");
|
||||
return;
|
||||
|
||||
@@ -1953,6 +1953,139 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 🆕 버튼 활성화 조건 설정 */}
|
||||
<div className="mt-4 border-t pt-4">
|
||||
<h5 className="mb-3 text-xs font-medium text-muted-foreground">버튼 활성화 조건</h5>
|
||||
|
||||
{/* 출발지/도착지 필수 체크 */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<Label htmlFor="require-location">출발지/도착지 필수</Label>
|
||||
<p className="text-xs text-muted-foreground">선택하지 않으면 버튼 비활성화</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="require-location"
|
||||
checked={config.action?.requireLocationFields === true}
|
||||
onCheckedChange={(checked) => onUpdateProperty("componentConfig.action.requireLocationFields", checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{config.action?.requireLocationFields && (
|
||||
<div className="mt-3 space-y-2 rounded-md bg-orange-50 p-3 dark:bg-orange-950">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label>출발지 필드명</Label>
|
||||
<Input
|
||||
placeholder="departure"
|
||||
value={config.action?.trackingDepartureField || "departure"}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.trackingDepartureField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label>도착지 필드명</Label>
|
||||
<Input
|
||||
placeholder="destination"
|
||||
value={config.action?.trackingArrivalField || "destination"}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.trackingArrivalField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 상태 기반 활성화 조건 */}
|
||||
<div className="mt-4 flex items-center justify-between">
|
||||
<div>
|
||||
<Label htmlFor="enable-on-status">상태 기반 활성화</Label>
|
||||
<p className="text-xs text-muted-foreground">특정 상태일 때만 버튼 활성화</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="enable-on-status"
|
||||
checked={config.action?.enableOnStatusCheck === true}
|
||||
onCheckedChange={(checked) => onUpdateProperty("componentConfig.action.enableOnStatusCheck", checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{config.action?.enableOnStatusCheck && (
|
||||
<div className="mt-3 space-y-2 rounded-md bg-purple-50 p-3 dark:bg-purple-950">
|
||||
<div>
|
||||
<Label>상태 조회 테이블</Label>
|
||||
<Select
|
||||
value={config.action?.statusCheckTableName || "vehicles"}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.statusCheckTableName", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{availableTables.map((table) => (
|
||||
<SelectItem key={table.name} value={table.name} className="text-xs">
|
||||
{table.label || table.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="mt-1 text-[10px] text-muted-foreground">
|
||||
상태를 조회할 테이블 (기본: vehicles)
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label>조회 키 필드</Label>
|
||||
<Input
|
||||
placeholder="user_id"
|
||||
value={config.action?.statusCheckKeyField || "user_id"}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.statusCheckKeyField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
<p className="mt-1 text-[10px] text-muted-foreground">
|
||||
현재 로그인 사용자 ID로 조회할 필드 (기본: user_id)
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label>상태 컬럼명</Label>
|
||||
<Input
|
||||
placeholder="status"
|
||||
value={config.action?.statusCheckField || "status"}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.statusCheckField", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
<p className="mt-1 text-[10px] text-muted-foreground">
|
||||
상태 값이 저장된 컬럼명 (기본: status)
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label>상태 조건</Label>
|
||||
<Select
|
||||
value={config.action?.statusConditionType || "enableOn"}
|
||||
onValueChange={(value) => onUpdateProperty("componentConfig.action.statusConditionType", value)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="enableOn">이 상태일 때만 활성화</SelectItem>
|
||||
<SelectItem value="disableOn">이 상태일 때 비활성화</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label>상태값 (쉼표로 구분)</Label>
|
||||
<Input
|
||||
placeholder="예: active, inactive"
|
||||
value={config.action?.statusConditionValues || ""}
|
||||
onChange={(e) => onUpdateProperty("componentConfig.action.statusConditionValues", e.target.value)}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
<p className="mt-1 text-[10px] text-muted-foreground">
|
||||
여러 상태값은 쉼표(,)로 구분
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="rounded-md bg-blue-50 p-3 dark:bg-blue-950">
|
||||
<p className="text-xs text-blue-900 dark:text-blue-100">
|
||||
<strong>사용 예시:</strong>
|
||||
|
||||
Reference in New Issue
Block a user