fix(RepeaterTable): 조회 컬럼 헤더 라벨 개선 및 코드 정리
헤더에 "컬럼명 - 옵션라벨" 형식으로 전체 정보 표시 옵션 변경 시 컬럼 너비 자동 재계산 API 검색 시 정확한 일치 검색(equals) 적용 디버그 로그 제거 설정 UI 라벨 사용자 친화적으로 변경
This commit is contained in:
@@ -53,8 +53,10 @@ function convertToRepeaterColumn(col: TableColumnConfig): RepeaterColumnConfig {
|
||||
enabled: true,
|
||||
options: col.lookup.options.map((option) => ({
|
||||
id: option.id,
|
||||
// displayLabel이 있으면 그것을 사용, 없으면 원래 label 사용
|
||||
// "컬럼명 - 옵션라벨" 형식으로 헤더에 표시
|
||||
label: option.displayLabel || option.label,
|
||||
// 헤더에 표시될 전체 라벨 (컬럼명 - 옵션라벨)
|
||||
headerLabel: `${col.label} - ${option.displayLabel || option.label}`,
|
||||
sourceType: "table" as const,
|
||||
tableConfig: {
|
||||
tableName: option.tableName,
|
||||
@@ -131,9 +133,19 @@ async function transformValue(
|
||||
}
|
||||
|
||||
try {
|
||||
// 정확히 일치하는 검색
|
||||
const response = await apiClient.post(
|
||||
`/table-management/tables/${transform.tableName}/data`,
|
||||
{ search: { [transform.matchColumn]: value }, size: 1, page: 1 }
|
||||
{
|
||||
search: {
|
||||
[transform.matchColumn]: {
|
||||
value: value,
|
||||
operator: "equals"
|
||||
}
|
||||
},
|
||||
size: 1,
|
||||
page: 1
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data.success && response.data.data?.data?.length > 0) {
|
||||
@@ -181,11 +193,20 @@ async function fetchExternalLookupValue(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 2. 외부 테이블에서 값 조회
|
||||
// 2. 외부 테이블에서 값 조회 (정확히 일치하는 검색)
|
||||
try {
|
||||
const response = await apiClient.post(
|
||||
`/table-management/tables/${externalLookup.tableName}/data`,
|
||||
{ search: { [externalLookup.matchColumn]: matchValue }, size: 1, page: 1 }
|
||||
{
|
||||
search: {
|
||||
[externalLookup.matchColumn]: {
|
||||
value: matchValue,
|
||||
operator: "equals"
|
||||
}
|
||||
},
|
||||
size: 1,
|
||||
page: 1
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data.success && response.data.data?.data?.length > 0) {
|
||||
@@ -218,10 +239,7 @@ async function fetchExternalValue(
|
||||
sourceData: any,
|
||||
formData: FormDataState
|
||||
): Promise<any> {
|
||||
console.log("📡 [fetchExternalValue] 시작:", { tableName, valueColumn, joinConditions });
|
||||
|
||||
if (joinConditions.length === 0) {
|
||||
console.warn("📡 [fetchExternalValue] 조인 조건이 없습니다.");
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -231,40 +249,29 @@ async function fetchExternalValue(
|
||||
for (const condition of joinConditions) {
|
||||
let value: any;
|
||||
|
||||
console.log("📡 [fetchExternalValue] 조건 처리:", { condition, rowData, sourceData, formData });
|
||||
|
||||
// 값 출처에 따라 가져오기 (4가지 소스 타입 지원)
|
||||
if (condition.sourceType === "row") {
|
||||
// 현재 행 데이터 (설정된 컬럼 필드)
|
||||
value = rowData[condition.sourceField];
|
||||
console.log("📡 [fetchExternalValue] row에서 값 가져옴:", { field: condition.sourceField, value });
|
||||
} else if (condition.sourceType === "sourceData") {
|
||||
// 원본 소스 테이블 데이터 (_sourceData)
|
||||
value = sourceData?.[condition.sourceField];
|
||||
console.log("📡 [fetchExternalValue] sourceData에서 값 가져옴:", { field: condition.sourceField, value });
|
||||
} else if (condition.sourceType === "formData") {
|
||||
// formData에서 가져오기 (다른 섹션)
|
||||
value = formData[condition.sourceField];
|
||||
console.log("📡 [fetchExternalValue] formData에서 값 가져옴:", { field: condition.sourceField, value });
|
||||
} else if (condition.sourceType === "externalTable" && condition.externalLookup) {
|
||||
// 외부 테이블에서 조회하여 가져오기
|
||||
console.log("📡 [fetchExternalValue] externalTable 조회 시작:", condition.externalLookup);
|
||||
value = await fetchExternalLookupValue(condition.externalLookup, rowData, sourceData, formData);
|
||||
console.log("📡 [fetchExternalValue] externalTable 조회 결과:", { value });
|
||||
}
|
||||
|
||||
if (value === undefined || value === null || value === "") {
|
||||
console.warn(`📡 [fetchExternalValue] 조인 조건의 필드 "${condition.sourceField}" 값이 없습니다. (sourceType: ${condition.sourceType})`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 값 변환이 필요한 경우 (예: 이름 → 코드) - 레거시 호환
|
||||
if (condition.transform) {
|
||||
console.log("📡 [fetchExternalValue] 값 변환 시작:", { originalValue: value, transform: condition.transform });
|
||||
value = await transformValue(value, condition.transform);
|
||||
console.log("📡 [fetchExternalValue] 값 변환 결과:", { transformedValue: value });
|
||||
if (value === undefined) {
|
||||
console.warn(`📡 [fetchExternalValue] 값 변환 후 결과가 없습니다. 원본 값: "${formData[condition.sourceField]}"`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -283,28 +290,21 @@ async function fetchExternalValue(
|
||||
value: convertedValue,
|
||||
operator: "equals"
|
||||
};
|
||||
console.log("📡 [fetchExternalValue] WHERE 조건 추가:", { targetColumn: condition.targetColumn, value: convertedValue });
|
||||
}
|
||||
|
||||
// API 호출
|
||||
console.log("📡 [fetchExternalValue] API 호출:", { tableName, whereConditions });
|
||||
const response = await apiClient.post(
|
||||
`/table-management/tables/${tableName}/data`,
|
||||
{ search: whereConditions, size: 1, page: 1 }
|
||||
);
|
||||
|
||||
console.log("📡 [fetchExternalValue] API 응답:", response.data);
|
||||
|
||||
if (response.data.success && response.data.data?.data?.length > 0) {
|
||||
const result = response.data.data.data[0][valueColumn];
|
||||
console.log("📡 [fetchExternalValue] 최종 결과:", { valueColumn, result });
|
||||
return result;
|
||||
return response.data.data.data[0][valueColumn];
|
||||
}
|
||||
|
||||
console.warn("📡 [fetchExternalValue] 조회 결과 없음");
|
||||
return undefined;
|
||||
} catch (error) {
|
||||
console.error("📡 [fetchExternalValue] 외부 테이블 조회 오류:", error);
|
||||
console.error("외부 테이블 조회 오류:", error);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -581,8 +581,6 @@ export function TableSectionRenderer({
|
||||
// 컬럼 모드/조회 옵션 변경 핸들러
|
||||
const handleDataSourceChange = useCallback(
|
||||
async (columnField: string, optionId: string) => {
|
||||
console.log("🔍 [handleDataSourceChange] 시작:", { columnField, optionId });
|
||||
|
||||
setActiveDataSources((prev) => ({
|
||||
...prev,
|
||||
[columnField]: optionId,
|
||||
@@ -590,23 +588,19 @@ export function TableSectionRenderer({
|
||||
|
||||
// 해당 컬럼의 모든 행 데이터 재조회
|
||||
const column = tableConfig.columns.find((col) => col.field === columnField);
|
||||
console.log("🔍 [handleDataSourceChange] 컬럼 찾기:", { column: column?.field, hasLookup: column?.lookup?.enabled });
|
||||
|
||||
// lookup 설정이 있는 경우 (새로운 조회 기능)
|
||||
if (column?.lookup?.enabled && column.lookup.options) {
|
||||
const selectedOption = column.lookup.options.find((opt) => opt.id === optionId);
|
||||
console.log("🔍 [handleDataSourceChange] 선택된 옵션:", { selectedOption, optionId });
|
||||
if (!selectedOption) return;
|
||||
|
||||
// sameTable 타입: 현재 행의 소스 데이터에서 값 복사 (외부 조회 필요 없음)
|
||||
if (selectedOption.type === "sameTable") {
|
||||
console.log("🔍 [handleDataSourceChange] sameTable 타입 - 소스 데이터에서 복사");
|
||||
const updatedData = tableData.map((row) => {
|
||||
// sourceField에서 값을 가져와 해당 컬럼에 복사
|
||||
// row에 _sourceData가 있으면 거기서, 없으면 row 자체에서 가져옴
|
||||
const sourceData = row._sourceData || row;
|
||||
const newValue = sourceData[selectedOption.valueColumn] ?? row[columnField];
|
||||
console.log("🔍 [handleDataSourceChange] sameTable 값 복사:", { valueColumn: selectedOption.valueColumn, sourceData, newValue });
|
||||
return { ...row, [columnField]: newValue };
|
||||
});
|
||||
|
||||
@@ -616,16 +610,8 @@ export function TableSectionRenderer({
|
||||
}
|
||||
|
||||
// 모든 행에 대해 새 값 조회
|
||||
console.log("🔍 [handleDataSourceChange] 외부 테이블 조회 시작:", {
|
||||
type: selectedOption.type,
|
||||
tableName: selectedOption.tableName,
|
||||
valueColumn: selectedOption.valueColumn,
|
||||
conditions: selectedOption.conditions,
|
||||
tableDataLength: tableData.length,
|
||||
});
|
||||
|
||||
const updatedData = await Promise.all(
|
||||
tableData.map(async (row, rowIndex) => {
|
||||
tableData.map(async (row) => {
|
||||
let newValue: any = row[columnField];
|
||||
|
||||
// 조인 조건 구성 (4가지 소스 타입 지원)
|
||||
@@ -657,13 +643,6 @@ export function TableSectionRenderer({
|
||||
};
|
||||
});
|
||||
|
||||
console.log(`🔍 [handleDataSourceChange] 행 ${rowIndex} 조회:`, {
|
||||
rowData: row,
|
||||
sourceData: row._sourceData,
|
||||
formData,
|
||||
joinConditions,
|
||||
});
|
||||
|
||||
// 외부 테이블에서 값 조회 (_sourceData 전달)
|
||||
const sourceData = row._sourceData || row;
|
||||
const value = await fetchExternalValue(
|
||||
@@ -675,8 +654,6 @@ export function TableSectionRenderer({
|
||||
formData
|
||||
);
|
||||
|
||||
console.log(`🔍 [handleDataSourceChange] 행 ${rowIndex} 조회 결과:`, { value });
|
||||
|
||||
if (value !== undefined) {
|
||||
newValue = value;
|
||||
}
|
||||
@@ -688,7 +665,6 @@ export function TableSectionRenderer({
|
||||
// 계산 필드 업데이트
|
||||
const calculatedData = calculateAll(updatedData);
|
||||
handleDataChange(calculatedData);
|
||||
console.log("🔍 [handleDataSourceChange] 완료:", { calculatedData });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user