fix: 필터 select 옵션에서 카테고리/엔티티 라벨이 올바르게 표시되도록 수정

- 백엔드: entityJoinService에서 _label 필드를 SELECT에 추가
- 백엔드: tableManagementService에 멀티테넌시 필터링 추가 (company_code)
- 백엔드: categorizeJoins에서 table_column_category_values를 명시적으로 dbJoins로 분류
- 백엔드: executeCachedLookup와 getTableData에 companyCode 파라미터 추가
- 프론트엔드: getColumnUniqueValues가 백엔드 조인 결과의 _name 필드를 사용하도록 수정
- 프론트엔드: TableSearchWidget에서 select 옵션 로드 로직 개선

이제 필터 select 박스에서 코드 대신 실제 이름(라벨)이 표시됩니다.
예: CATEGORY_148700 → 정상, topseal_admin → 탑씰 관리자 계정
This commit is contained in:
kjs
2025-11-12 14:02:58 +09:00
parent 58870237b6
commit 71fd3f5ee7
4 changed files with 203 additions and 73 deletions

View File

@@ -62,7 +62,7 @@ export function TableSearchWidget({ component }: TableSearchWidgetProps) {
}
}, [registeredTables, selectedTableId, autoSelectFirstTable, setSelectedTableId]);
// 현재 테이블의 저장된 필터 불러오기 및 select 옵션 로드
// 현재 테이블의 저장된 필터 불러오기
useEffect(() => {
if (currentTable?.tableName) {
const storageKey = `table_filters_${currentTable.tableName}`;
@@ -89,36 +89,54 @@ export function TableSearchWidget({ component }: TableSearchWidgetProps) {
}));
setActiveFilters(activeFiltersList);
// select 타입 필터들의 옵션 로드
const loadSelectOptions = async () => {
const newOptions: Record<string, Array<{ label: string; value: string }>> = {};
for (const filter of activeFiltersList) {
if (filter.filterType === "select" && currentTable.getColumnUniqueValues) {
try {
const options = await currentTable.getColumnUniqueValues(filter.columnName);
newOptions[filter.columnName] = options;
console.log("✅ [TableSearchWidget] select 옵션 로드:", {
columnName: filter.columnName,
optionCount: options.length,
});
} catch (error) {
console.error("select 옵션 로드 실패:", filter.columnName, error);
}
}
}
setSelectOptions(newOptions);
};
loadSelectOptions();
} catch (error) {
console.error("저장된 필터 불러오기 실패:", error);
}
}
}
}, [currentTable?.tableName, currentTable?.getColumnUniqueValues]);
}, [currentTable?.tableName]);
// select 옵션 로드 (activeFilters 또는 dataCount 변경 시)
useEffect(() => {
if (!currentTable?.getColumnUniqueValues || activeFilters.length === 0) {
return;
}
const loadSelectOptions = async () => {
const selectFilters = activeFilters.filter(f => f.filterType === "select");
if (selectFilters.length === 0) {
return;
}
console.log("🔄 [TableSearchWidget] select 옵션 로드 시작:", {
activeFiltersCount: activeFilters.length,
selectFiltersCount: selectFilters.length,
dataCount: currentTable.dataCount,
});
const newOptions: Record<string, Array<{ label: string; value: string }>> = {};
for (const filter of selectFilters) {
try {
const options = await currentTable.getColumnUniqueValues(filter.columnName);
newOptions[filter.columnName] = options;
console.log("✅ [TableSearchWidget] select 옵션 로드:", {
columnName: filter.columnName,
optionCount: options.length,
options: options.slice(0, 5),
});
} catch (error) {
console.error("❌ [TableSearchWidget] select 옵션 로드 실패:", filter.columnName, error);
}
}
console.log("✅ [TableSearchWidget] 최종 selectOptions:", newOptions);
setSelectOptions(newOptions);
};
loadSelectOptions();
}, [activeFilters, currentTable?.dataCount, currentTable?.getColumnUniqueValues]);
// 디버깅: 현재 테이블 정보 로깅
useEffect(() => {
@@ -193,13 +211,13 @@ export function TableSearchWidget({ component }: TableSearchWidgetProps) {
onValueChange={(val) => handleFilterChange(filter.columnName, val)}
>
<SelectTrigger className="h-8 text-xs sm:h-9 sm:text-sm">
<SelectValue placeholder={column?.columnLabel} />
<SelectValue placeholder={column?.columnLabel || "선택"} />
</SelectTrigger>
<SelectContent>
{options.length === 0 ? (
<SelectItem value="" disabled>
<div className="px-2 py-1.5 text-xs text-muted-foreground">
</SelectItem>
</div>
) : (
options.map((option) => (
<SelectItem key={option.value} value={option.value}>