Compare commits
No commits in common. "f84c06a7a7bbfcdc59126d2d13ad89c37cd13acc" and "d9088816a72db504b25357bb3d7aa2f1d1c9d707" have entirely different histories.
f84c06a7a7
...
d9088816a7
|
|
@ -4,17 +4,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Plus, Trash2, Check, ChevronsUpDown } from "lucide-react";
|
import { Plus, Trash2 } 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;
|
||||||
|
|
@ -52,7 +49,6 @@ 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(() => {
|
||||||
|
|
@ -242,74 +238,27 @@ export function FlowConditionBuilder({
|
||||||
className="h-8"
|
className="h-8"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Popover
|
<Select value={cond.column} onValueChange={(value) => updateCondition(index, "column", value)}>
|
||||||
open={columnComboboxOpen[index] || false}
|
<SelectTrigger className="h-8">
|
||||||
onOpenChange={(open) => setColumnComboboxOpen({ ...columnComboboxOpen, [index]: open })}
|
<SelectValue placeholder="컬럼 선택" />
|
||||||
>
|
</SelectTrigger>
|
||||||
<PopoverTrigger asChild>
|
<SelectContent>
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
role="combobox"
|
|
||||||
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) => {
|
{columns.map((col, idx) => {
|
||||||
const columnName = col.column_name || col.columnName || "";
|
const columnName = col.column_name || col.columnName || "";
|
||||||
const dataType = col.data_type || col.dataType || "";
|
const dataType = col.data_type || col.dataType || "";
|
||||||
const displayName = col.displayName || col.display_name || columnName;
|
const displayName = col.displayName || col.display_name || columnName;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CommandItem
|
<SelectItem key={`${columnName}-${idx}`} value={columnName}>
|
||||||
key={`${columnName}-${idx}`}
|
|
||||||
value={columnName}
|
|
||||||
onSelect={(currentValue) => {
|
|
||||||
updateCondition(index, "column", currentValue);
|
|
||||||
setColumnComboboxOpen({ ...columnComboboxOpen, [index]: false });
|
|
||||||
}}
|
|
||||||
className="text-xs"
|
|
||||||
>
|
|
||||||
<Check
|
|
||||||
className={cn(
|
|
||||||
"mr-2 h-3 w-3",
|
|
||||||
cond.column === columnName ? "opacity-100" : "opacity-0",
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-medium">{displayName}</span>
|
<span className="font-medium">{displayName}</span>
|
||||||
<span className="text-gray-500">({dataType})</span>
|
<span className="text-xs text-gray-500">({dataType})</span>
|
||||||
</div>
|
</div>
|
||||||
</CommandItem>
|
</SelectItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</CommandGroup>
|
</SelectContent>
|
||||||
</CommandList>
|
</Select>
|
||||||
</Command>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,6 @@ const getApiBaseUrl = (): string => {
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const currentHost = window.location.hostname;
|
const currentHost = window.location.hostname;
|
||||||
const currentPort = window.location.port;
|
const currentPort = window.location.port;
|
||||||
const protocol = window.location.protocol;
|
|
||||||
|
|
||||||
// 프로덕션 환경: v1.vexplor.com → api.vexplor.com
|
|
||||||
if (currentHost === "v1.vexplor.com") {
|
|
||||||
return "https://api.vexplor.com/api";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 로컬 개발환경: localhost:9771 또는 localhost:3000 → localhost:8080
|
// 로컬 개발환경: localhost:9771 또는 localhost:3000 → localhost:8080
|
||||||
if (
|
if (
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DashboardElement } from "@/components/admin/dashboard/types";
|
import { DashboardElement } from "@/components/admin/dashboard/types";
|
||||||
import { API_BASE_URL } from "./client";
|
|
||||||
|
// API 기본 설정
|
||||||
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "/api";
|
||||||
|
|
||||||
// 토큰 가져오기 (실제 인증 시스템에 맞게 수정)
|
// 토큰 가져오기 (실제 인증 시스템에 맞게 수정)
|
||||||
function getAuthToken(): string | null {
|
function getAuthToken(): string | null {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue