feat(repeat-screen-modal): 집계 저장 및 채번 규칙 값 저장 기능 추가
- RepeatScreenModal 집계 결과를 연관 테이블에 저장하는 기능 추가 - ButtonPrimary 저장 시 채번 규칙 값(shipment_plan_no) 함께 저장 - _repeatScreenModal_* 데이터 감지 시 메인 테이블 중복 저장 방지 - 기존 행 수정 모드(_isEditing) 지원 - AggregationSaveConfig 타입 및 ConfigPanel UI 추가
This commit is contained in:
@@ -766,7 +766,7 @@ function AggregationConfigItem({
|
||||
const currentSourceType = agg.sourceType || "column";
|
||||
|
||||
return (
|
||||
<div className="border rounded p-2 space-y-1.5 bg-background overflow-hidden min-w-0">
|
||||
<div className="border rounded p-2 space-y-1.5 bg-background min-w-0">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-1 min-w-0">
|
||||
<Badge
|
||||
@@ -922,6 +922,161 @@ function AggregationConfigItem({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 🆕 v3.9: 저장 설정 */}
|
||||
<AggregationSaveConfigSection
|
||||
agg={agg}
|
||||
sourceTable={sourceTable}
|
||||
allTables={allTables}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 🆕 v3.9: 집계 저장 설정 섹션
|
||||
function AggregationSaveConfigSection({
|
||||
agg,
|
||||
sourceTable,
|
||||
allTables,
|
||||
onUpdate,
|
||||
}: {
|
||||
agg: AggregationConfig;
|
||||
sourceTable: string;
|
||||
allTables: { tableName: string; displayName?: string }[];
|
||||
onUpdate: (updates: Partial<AggregationConfig>) => void;
|
||||
}) {
|
||||
const saveConfig = agg.saveConfig || { enabled: false, autoSave: false, targetTable: "", targetColumn: "", joinKey: { sourceField: "", targetField: "" } };
|
||||
|
||||
const updateSaveConfig = (updates: Partial<typeof saveConfig>) => {
|
||||
onUpdate({
|
||||
saveConfig: {
|
||||
...saveConfig,
|
||||
...updates,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-2 pt-2 border-t border-dashed">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-[9px] font-semibold">연관 테이블 저장</Label>
|
||||
<Switch
|
||||
checked={saveConfig.enabled}
|
||||
onCheckedChange={(checked) => updateSaveConfig({ enabled: checked })}
|
||||
className="scale-[0.6]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{saveConfig.enabled && (
|
||||
<div className="space-y-2 p-2 bg-blue-50/50 dark:bg-blue-900/20 rounded border border-blue-200 dark:border-blue-800">
|
||||
{/* 자동 저장 옵션 */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<Label className="text-[9px]">자동 저장</Label>
|
||||
<p className="text-[8px] text-muted-foreground">
|
||||
레이아웃에 없어도 저장
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={saveConfig.autoSave}
|
||||
onCheckedChange={(checked) => updateSaveConfig({ autoSave: checked })}
|
||||
className="scale-[0.6]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 대상 테이블 */}
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[9px]">대상 테이블</Label>
|
||||
<Select
|
||||
value={saveConfig.targetTable}
|
||||
onValueChange={(value) => {
|
||||
updateSaveConfig({ targetTable: value, targetColumn: "" });
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="h-6 text-[10px]">
|
||||
<SelectValue placeholder="테이블 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{allTables.map((t) => (
|
||||
<SelectItem key={t.tableName} value={t.tableName} className="text-[10px]">
|
||||
{t.displayName || t.tableName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* 대상 컬럼 */}
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[9px]">대상 컬럼</Label>
|
||||
<SourceColumnSelector
|
||||
sourceTable={saveConfig.targetTable}
|
||||
value={saveConfig.targetColumn}
|
||||
onChange={(value) => updateSaveConfig({ targetColumn: value })}
|
||||
placeholder="컬럼 선택"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 조인 키 설정 */}
|
||||
<div className="space-y-2">
|
||||
<Label className="text-[9px]">조인 키</Label>
|
||||
<div className="space-y-1.5">
|
||||
<div className="space-y-0.5">
|
||||
<span className="text-[8px] text-muted-foreground">카드 키 (현재 카드 데이터)</span>
|
||||
<SourceColumnSelector
|
||||
sourceTable={sourceTable}
|
||||
value={saveConfig.joinKey?.sourceField || ""}
|
||||
onChange={(value) =>
|
||||
updateSaveConfig({
|
||||
joinKey: { ...saveConfig.joinKey, sourceField: value },
|
||||
})
|
||||
}
|
||||
placeholder="카드 키 선택"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<span className="text-[10px] text-muted-foreground">↓</span>
|
||||
</div>
|
||||
<div className="space-y-0.5">
|
||||
<span className="text-[8px] text-muted-foreground">대상 키 (업데이트할 레코드 식별)</span>
|
||||
<SourceColumnSelector
|
||||
sourceTable={saveConfig.targetTable}
|
||||
value={saveConfig.joinKey?.targetField || ""}
|
||||
onChange={(value) =>
|
||||
updateSaveConfig({
|
||||
joinKey: { ...saveConfig.joinKey, targetField: value },
|
||||
})
|
||||
}
|
||||
placeholder="대상 키 선택"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 설정 요약 */}
|
||||
{saveConfig.targetTable && saveConfig.targetColumn && (
|
||||
<div className="p-1.5 bg-white/50 dark:bg-black/20 rounded text-[9px] space-y-1">
|
||||
<div>
|
||||
<span className="font-medium">저장 경로:</span>
|
||||
{saveConfig.autoSave && (
|
||||
<Badge variant="secondary" className="ml-1 text-[8px] px-1 py-0">
|
||||
자동
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<div className="font-mono text-blue-600 dark:text-blue-400 break-all">
|
||||
{saveConfig.targetTable}.{saveConfig.targetColumn}
|
||||
</div>
|
||||
{saveConfig.joinKey?.sourceField && saveConfig.joinKey?.targetField && (
|
||||
<div className="text-[8px] text-muted-foreground">
|
||||
조인: {saveConfig.joinKey.sourceField} → {saveConfig.joinKey.targetField}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user