플로우 로그기능 수정

This commit is contained in:
kjs
2025-10-21 14:21:29 +09:00
parent 93675100da
commit 74ebb565e6
10 changed files with 154 additions and 56 deletions

View File

@@ -243,14 +243,20 @@ export function FlowConditionBuilder({
<SelectValue placeholder="컬럼 선택" />
</SelectTrigger>
<SelectContent>
{columns.map((col) => (
<SelectItem key={col.columnName} value={col.columnName}>
<div className="flex items-center gap-2">
<span className="font-medium">{col.displayName || col.columnName}</span>
<span className="text-xs text-gray-500">({col.dataType})</span>
</div>
</SelectItem>
))}
{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 (
<SelectItem key={`${columnName}-${idx}`} value={columnName}>
<div className="flex items-center gap-2">
<span className="font-medium">{displayName}</span>
<span className="text-xs text-gray-500">({dataType})</span>
</div>
</SelectItem>
);
})}
</SelectContent>
</Select>
)}

View File

@@ -666,8 +666,12 @@ export function FlowStepPanel({
{loadingColumns
? "컬럼 로딩 중..."
: formData.statusColumn
? columns.find((col) => col.columnName === formData.statusColumn)?.columnName ||
formData.statusColumn
? (() => {
const col = columns.find(
(c) => (c.column_name || c.columnName) === formData.statusColumn,
);
return col ? col.column_name || col.columnName : formData.statusColumn;
})()
: "상태 컬럼 선택"}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
@@ -678,27 +682,32 @@ export function FlowStepPanel({
<CommandList>
<CommandEmpty> .</CommandEmpty>
<CommandGroup>
{columns.map((column) => (
<CommandItem
key={column.columnName}
value={column.columnName}
onSelect={() => {
setFormData({ ...formData, statusColumn: column.columnName });
setOpenStatusColumnCombobox(false);
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
formData.statusColumn === column.columnName ? "opacity-100" : "opacity-0",
)}
/>
<div>
<div>{column.columnName}</div>
<div className="text-xs text-gray-500">({column.dataType})</div>
</div>
</CommandItem>
))}
{columns.map((column, idx) => {
const columnName = column.column_name || column.columnName || "";
const dataType = column.data_type || column.dataType || "";
return (
<CommandItem
key={`${columnName}-${idx}`}
value={columnName}
onSelect={() => {
setFormData({ ...formData, statusColumn: columnName });
setOpenStatusColumnCombobox(false);
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
formData.statusColumn === columnName ? "opacity-100" : "opacity-0",
)}
/>
<div>
<div>{columnName}</div>
<div className="text-xs text-gray-500">({dataType})</div>
</div>
</CommandItem>
);
})}
</CommandGroup>
</CommandList>
</Command>

View File

@@ -397,6 +397,7 @@ export function FlowWidget({ component, onStepClick }: FlowWidgetProps) {
<TableHead className="w-[100px]"> ID</TableHead>
<TableHead className="w-[140px]"> </TableHead>
<TableHead className="w-[100px]"></TableHead>
<TableHead className="w-[150px]">DB </TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
@@ -450,6 +451,21 @@ export function FlowWidget({ component, onStepClick }: FlowWidgetProps) {
)}
</TableCell>
<TableCell className="text-xs">{log.changedBy}</TableCell>
<TableCell className="text-xs">
{log.dbConnectionName ? (
<span
className={
log.dbConnectionName === "내부 데이터베이스"
? "text-blue-600"
: "text-green-600"
}
>
{log.dbConnectionName}
</span>
) : (
<span className="text-muted-foreground">-</span>
)}
</TableCell>
<TableCell className="text-xs">
{log.sourceTable || "-"}
{log.targetTable && log.targetTable !== log.sourceTable && (

View File

@@ -21,6 +21,12 @@ import {
const API_BASE = process.env.NEXT_PUBLIC_API_URL || "/api";
// 토큰 가져오기
function getAuthToken(): string | null {
if (typeof window === "undefined") return null;
return localStorage.getItem("authToken") || sessionStorage.getItem("authToken");
}
// ============================================
// 플로우 정의 API
// ============================================
@@ -364,10 +370,12 @@ export async function getAllStepCounts(flowId: number): Promise<ApiResponse<Flow
*/
export async function moveData(data: MoveDataRequest): Promise<ApiResponse<{ success: boolean }>> {
try {
const token = getAuthToken();
const response = await fetch(`${API_BASE}/flow/move`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...(token && { Authorization: `Bearer ${token}` }),
},
credentials: "include",
body: JSON.stringify(data),
@@ -404,10 +412,12 @@ export async function moveBatchData(
data: MoveBatchDataRequest,
): Promise<ApiResponse<{ success: boolean; results: any[] }>> {
try {
const token = getAuthToken();
const response = await fetch(`${API_BASE}/flow/move-batch`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...(token && { Authorization: `Bearer ${token}` }),
},
credentials: "include",
body: JSON.stringify(data),

View File

@@ -148,6 +148,15 @@ export interface FlowAuditLog {
note?: string;
fromStepName?: string;
toStepName?: string;
moveType?: "status" | "table" | "both";
sourceTable?: string;
targetTable?: string;
sourceDataId?: string;
targetDataId?: string;
statusFrom?: string;
statusTo?: string;
dbConnectionId?: number;
dbConnectionName?: string;
}
// ============================================