This commit is contained in:
dohyeons 2025-10-23 18:11:45 +09:00
commit ea9ed488e8
1 changed files with 72 additions and 21 deletions

View File

@ -4,14 +4,17 @@
*/ */
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { Plus, Trash2 } from "lucide-react"; import { Plus, Trash2, Check, ChevronsUpDown } from "lucide-react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { FlowConditionGroup, FlowCondition, ConditionOperator } from "@/types/flow"; import { FlowConditionGroup, FlowCondition, ConditionOperator } from "@/types/flow";
import { getTableColumns } from "@/lib/api/tableManagement"; import { getTableColumns } from "@/lib/api/tableManagement";
import { cn } from "@/lib/utils";
interface FlowConditionBuilderProps { interface FlowConditionBuilderProps {
flowId: number; flowId: number;
@ -49,6 +52,7 @@ export function FlowConditionBuilder({
const [loadingColumns, setLoadingColumns] = useState(false); const [loadingColumns, setLoadingColumns] = useState(false);
const [conditionType, setConditionType] = useState<"AND" | "OR">(condition?.type || "AND"); const [conditionType, setConditionType] = useState<"AND" | "OR">(condition?.type || "AND");
const [conditions, setConditions] = useState<FlowCondition[]>(condition?.conditions || []); const [conditions, setConditions] = useState<FlowCondition[]>(condition?.conditions || []);
const [columnComboboxOpen, setColumnComboboxOpen] = useState<Record<number, boolean>>({});
// condition prop이 변경될 때 상태 동기화 // condition prop이 변경될 때 상태 동기화
useEffect(() => { useEffect(() => {
@ -238,27 +242,74 @@ export function FlowConditionBuilder({
className="h-8" className="h-8"
/> />
) : ( ) : (
<Select value={cond.column} onValueChange={(value) => updateCondition(index, "column", value)}> <Popover
<SelectTrigger className="h-8"> open={columnComboboxOpen[index] || false}
<SelectValue placeholder="컬럼 선택" /> onOpenChange={(open) => setColumnComboboxOpen({ ...columnComboboxOpen, [index]: open })}
</SelectTrigger> >
<SelectContent> <PopoverTrigger asChild>
{columns.map((col, idx) => { <Button
const columnName = col.column_name || col.columnName || ""; variant="outline"
const dataType = col.data_type || col.dataType || ""; role="combobox"
const displayName = col.displayName || col.display_name || columnName; aria-expanded={columnComboboxOpen[index] || false}
className="h-8 w-full justify-between text-xs font-normal"
>
{cond.column
? (() => {
const col = columns.find((c) => (c.column_name || c.columnName) === cond.column);
const displayName = col?.displayName || col?.display_name || cond.column;
const dataType = col?.data_type || col?.dataType || "";
return (
<span className="flex items-center gap-2">
<span className="font-medium">{displayName}</span>
{dataType && <span className="text-gray-500">({dataType})</span>}
</span>
);
})()
: "컬럼 선택"}
<ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px] p-0" align="start">
<Command>
<CommandInput placeholder="컬럼 검색..." className="h-8 text-xs" />
<CommandList>
<CommandEmpty className="py-2 text-center text-xs text-gray-500">
.
</CommandEmpty>
<CommandGroup>
{columns.map((col, idx) => {
const columnName = col.column_name || col.columnName || "";
const dataType = col.data_type || col.dataType || "";
const displayName = col.displayName || col.display_name || columnName;
return ( return (
<SelectItem key={`${columnName}-${idx}`} value={columnName}> <CommandItem
<div className="flex items-center gap-2"> key={`${columnName}-${idx}`}
<span className="font-medium">{displayName}</span> value={columnName}
<span className="text-xs text-gray-500">({dataType})</span> onSelect={(currentValue) => {
</div> updateCondition(index, "column", currentValue);
</SelectItem> setColumnComboboxOpen({ ...columnComboboxOpen, [index]: false });
); }}
})} className="text-xs"
</SelectContent> >
</Select> <Check
className={cn(
"mr-2 h-3 w-3",
cond.column === columnName ? "opacity-100" : "opacity-0",
)}
/>
<div className="flex items-center gap-2">
<span className="font-medium">{displayName}</span>
<span className="text-gray-500">({dataType})</span>
</div>
</CommandItem>
);
})}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
)} )}
</div> </div>