feat: Enhance V2Repeater and configuration panel with source detail auto-fetching
- Added support for automatic fetching of detail rows from the master data in the V2Repeater component, improving data management. - Introduced a new configuration option in the V2RepeaterConfigPanel to enable source detail auto-fetching, allowing users to specify detail table and foreign key settings. - Enhanced the V2Repeater component to handle entity joins for loading data, optimizing data retrieval processes. - Updated the V2RepeaterProps and V2RepeaterConfig interfaces to include new properties for grouped data and source detail configuration, ensuring type safety and clarity in component usage. - Improved logging for data loading processes to provide better insights during development and debugging.
This commit is contained in:
@@ -31,6 +31,7 @@ import {
|
||||
Wand2,
|
||||
Check,
|
||||
ChevronsUpDown,
|
||||
ListTree,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
Command,
|
||||
@@ -983,6 +984,133 @@ export const V2RepeaterConfigPanel: React.FC<V2RepeaterConfigPanelProps> = ({
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* 소스 디테일 자동 조회 설정 */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="enableSourceDetail"
|
||||
checked={!!config.sourceDetailConfig}
|
||||
onCheckedChange={(checked) => {
|
||||
if (checked) {
|
||||
updateConfig({
|
||||
sourceDetailConfig: {
|
||||
tableName: "",
|
||||
foreignKey: "",
|
||||
parentKey: "",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
updateConfig({ sourceDetailConfig: undefined });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="enableSourceDetail" className="text-xs font-medium flex items-center gap-1">
|
||||
<ListTree className="h-3 w-3" />
|
||||
소스 디테일 자동 조회
|
||||
</label>
|
||||
</div>
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
모달에서 전달받은 마스터 데이터의 디테일 행을 자동으로 조회하여 리피터에 채웁니다.
|
||||
</p>
|
||||
|
||||
{config.sourceDetailConfig && (
|
||||
<div className="space-y-2 rounded border border-violet-200 bg-violet-50 p-2">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[10px]">디테일 테이블</Label>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
className="h-7 w-full justify-between text-xs"
|
||||
>
|
||||
{config.sourceDetailConfig.tableName
|
||||
? (allTables.find(t => t.tableName === config.sourceDetailConfig!.tableName)?.displayName || config.sourceDetailConfig.tableName)
|
||||
: "테이블 선택..."
|
||||
}
|
||||
<ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="p-0"
|
||||
style={{ width: "var(--radix-popover-trigger-width)" }}
|
||||
align="start"
|
||||
>
|
||||
<Command>
|
||||
<CommandInput placeholder="테이블 검색..." className="text-xs" />
|
||||
<CommandList className="max-h-48">
|
||||
<CommandEmpty className="text-xs py-3 text-center">테이블을 찾을 수 없습니다.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{allTables.map((table) => (
|
||||
<CommandItem
|
||||
key={table.tableName}
|
||||
value={`${table.tableName} ${table.displayName}`}
|
||||
onSelect={() => {
|
||||
updateConfig({
|
||||
sourceDetailConfig: {
|
||||
...config.sourceDetailConfig!,
|
||||
tableName: table.tableName,
|
||||
},
|
||||
});
|
||||
}}
|
||||
className="text-xs"
|
||||
>
|
||||
<Check className={cn("mr-2 h-3 w-3", config.sourceDetailConfig!.tableName === table.tableName ? "opacity-100" : "opacity-0")} />
|
||||
<span>{table.displayName}</span>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[10px]">디테일 FK 컬럼</Label>
|
||||
<Input
|
||||
value={config.sourceDetailConfig.foreignKey || ""}
|
||||
onChange={(e) =>
|
||||
updateConfig({
|
||||
sourceDetailConfig: {
|
||||
...config.sourceDetailConfig!,
|
||||
foreignKey: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
placeholder="예: order_no"
|
||||
className="h-7 text-xs"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[10px]">마스터 키 컬럼</Label>
|
||||
<Input
|
||||
value={config.sourceDetailConfig.parentKey || ""}
|
||||
onChange={(e) =>
|
||||
updateConfig({
|
||||
sourceDetailConfig: {
|
||||
...config.sourceDetailConfig!,
|
||||
parentKey: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
placeholder="예: order_no"
|
||||
className="h-7 text-xs"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-[10px] text-violet-600">
|
||||
마스터에서 [{config.sourceDetailConfig.parentKey || "?"}] 추출 →
|
||||
{" "}{config.sourceDetailConfig.tableName || "?"}.{config.sourceDetailConfig.foreignKey || "?"} 로 조회
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* 기능 옵션 */}
|
||||
<div className="space-y-3">
|
||||
<Label className="text-xs font-medium">기능 옵션</Label>
|
||||
|
||||
Reference in New Issue
Block a user