fix: 분할 패널 필터링 수정 및 디버깅 로그 제거

문제:
- 분할 패널에서 필터 입력 시 검색이 제대로 작동하지 않음
- 백엔드가 {value: '전자', operator: 'contains'} 형태를 처리하지 못함

원인:
- buildAdvancedSearchCondition이 필터 객체의 value 속성을 추출하지 않음
- 객체를 직접 문자열로 변환하여 '[object Object]'로 검색됨

해결:
1. tableManagementService.buildAdvancedSearchCondition 수정:
   - {value, operator} 형태의 필터 객체 감지
   - actualValue 추출 및 operator 처리
   - 모든 웹타입 케이스에 actualValue 전달

2. 프론트엔드 디버깅 로그 제거:
   - SplitPanelLayoutComponent의 console.log 제거
   - 필터, 컬럼 가시성, API 호출 로그 정리

테스트 필요:
- 분할 패널에서 필터 입력 → 정상 검색 확인
- 텍스트, 날짜, 숫자, 코드 타입 필터 동작 확인
This commit is contained in:
kjs 2025-11-12 16:39:50 +09:00
parent 7b84a81a96
commit 77faba7e77
2 changed files with 48 additions and 51 deletions

View File

@ -1069,12 +1069,28 @@ export class TableManagementService {
paramCount: number;
} | null> {
try {
// 🔧 {value, operator} 형태의 필터 객체 처리
let actualValue = value;
let operator = "contains"; // 기본값
if (typeof value === "object" && value !== null && "value" in value) {
actualValue = value.value;
operator = value.operator || "contains";
logger.info("🔍 필터 객체 처리:", {
columnName,
originalValue: value,
actualValue,
operator,
});
}
// "__ALL__" 값이거나 빈 값이면 필터 조건을 적용하지 않음
if (
value === "__ALL__" ||
value === "" ||
value === null ||
value === undefined
actualValue === "__ALL__" ||
actualValue === "" ||
actualValue === null ||
actualValue === undefined
) {
return null;
}
@ -1083,12 +1099,22 @@ export class TableManagementService {
const columnInfo = await this.getColumnWebTypeInfo(tableName, columnName);
if (!columnInfo) {
// 컬럼 정보가 없으면 기본 문자열 검색
return {
whereClause: `${columnName}::text ILIKE $${paramIndex}`,
values: [`%${value}%`],
paramCount: 1,
};
// 컬럼 정보가 없으면 operator에 따른 기본 검색
switch (operator) {
case "equals":
return {
whereClause: `${columnName}::text = $${paramIndex}`,
values: [actualValue],
paramCount: 1,
};
case "contains":
default:
return {
whereClause: `${columnName}::text ILIKE $${paramIndex}`,
values: [`%${actualValue}%`],
paramCount: 1,
};
}
}
const webType = columnInfo.webType;
@ -1097,17 +1123,17 @@ export class TableManagementService {
switch (webType) {
case "date":
case "datetime":
return this.buildDateRangeCondition(columnName, value, paramIndex);
return this.buildDateRangeCondition(columnName, actualValue, paramIndex);
case "number":
case "decimal":
return this.buildNumberRangeCondition(columnName, value, paramIndex);
return this.buildNumberRangeCondition(columnName, actualValue, paramIndex);
case "code":
return await this.buildCodeSearchCondition(
tableName,
columnName,
value,
actualValue,
paramIndex
);
@ -1115,15 +1141,15 @@ export class TableManagementService {
return await this.buildEntitySearchCondition(
tableName,
columnName,
value,
actualValue,
paramIndex
);
default:
// 기본 문자열 검색
// 기본 문자열 검색 (actualValue 사용)
return {
whereClause: `${columnName}::text ILIKE $${paramIndex}`,
values: [`%${value}%`],
values: [`%${actualValue}%`],
paramCount: 1,
};
}
@ -1133,9 +1159,14 @@ export class TableManagementService {
error
);
// 오류 시 기본 검색으로 폴백
let fallbackValue = value;
if (typeof value === "object" && value !== null && "value" in value) {
fallbackValue = value.value;
}
return {
whereClause: `${columnName}::text ILIKE $${paramIndex}`,
values: [`%${value}%`],
values: [`%${fallbackValue}%`],
paramCount: 1,
};
}

View File

@ -185,11 +185,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// 🔄 컬럼 가시성 및 순서 처리
const visibleLeftColumns = useMemo(() => {
const displayColumns = componentConfig.leftPanel?.columns || [];
console.log("🔍 [분할패널] visibleLeftColumns 계산:", {
displayColumns: displayColumns.length,
leftColumnVisibility: leftColumnVisibility.length,
leftColumnOrder: leftColumnOrder.length,
});
if (displayColumns.length === 0) return [];
@ -202,7 +197,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const colName = typeof col === 'string' ? col : (col.name || col.columnName);
return visibilityMap.get(colName) !== false;
});
console.log("✅ [분할패널] 가시성 적용 후:", columns.length);
}
// 🔧 컬럼 순서 적용
@ -215,7 +209,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const bIndex = orderMap.get(bName) ?? 999;
return aIndex - bIndex;
});
console.log("✅ [분할패널] 순서 적용 후:", columns.map((c: any) => typeof c === 'string' ? c : (c.name || c.columnName)));
}
return columns;
@ -258,11 +251,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// 🎯 필터 조건을 API에 전달 (entityJoinApi 사용)
const filters = Object.keys(searchValues).length > 0 ? searchValues : undefined;
console.log("📡 [분할패널] API 호출 시작:", {
tableName: leftTableName,
filters,
searchValues,
});
const result = await entityJoinApi.getTableDataWithJoins(leftTableName, {
page: 1,
@ -271,11 +259,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
enableEntityJoin: true, // 엔티티 조인 활성화
});
console.log("📡 [분할패널] API 응답:", {
success: result.success,
dataLength: result.data?.length || 0,
totalItems: result.totalItems,
});
// 가나다순 정렬 (좌측 패널의 표시 컬럼 기준)
const leftColumn = componentConfig.rightPanel?.relation?.leftColumn;
@ -946,12 +929,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// 🔧 컬럼 가시성 변경 시 localStorage에 저장 및 순서 업데이트
useEffect(() => {
const leftTableName = componentConfig.leftPanel?.tableName;
console.log("🔍 [분할패널] 컬럼 가시성 변경 감지:", {
leftColumnVisibility: leftColumnVisibility.length,
leftTableName,
currentUserId,
visibility: leftColumnVisibility,
});
if (leftColumnVisibility.length > 0 && leftTableName && currentUserId) {
// 순서 업데이트
@ -959,13 +936,11 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
.map((cv) => cv.columnName)
.filter((name) => name !== "__checkbox__"); // 체크박스 제외
console.log("✅ [분할패널] 컬럼 순서 업데이트:", newOrder);
setLeftColumnOrder(newOrder);
// localStorage에 저장
const storageKey = `table_column_visibility_${leftTableName}_${currentUserId}`;
localStorage.setItem(storageKey, JSON.stringify(leftColumnVisibility));
console.log("💾 [분할패널] localStorage 저장:", storageKey);
}
}, [leftColumnVisibility, componentConfig.leftPanel?.tableName, currentUserId]);
@ -979,16 +954,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// 🔄 필터 변경 시 데이터 다시 로드
useEffect(() => {
console.log("🔍 [분할패널] 필터 변경 감지:", {
leftFilters: leftFilters.length,
filters: leftFilters,
isDesignMode,
autoLoad: componentConfig.autoLoad,
searchValues,
});
if (!isDesignMode && componentConfig.autoLoad !== false) {
console.log("✅ [분할패널] loadLeftData 호출 (필터 변경)");
loadLeftData();
}
// eslint-disable-next-line react-hooks/exhaustive-deps