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:
@@ -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}>
|
||||
|
||||
Reference in New Issue
Block a user