fix: SelectedItemsDetailInput Select 빈 값 에러 수정 및 inputType 디버깅 로그 추가
- Select 컴포넌트에서 빈 문자열 value를 가진 SelectItem 제거 - category/code 타입 필드의 옵션 로딩 디버깅 로그 추가 - 빈 값 필터링으로 'SelectItem must not have empty value' 에러 해결 - codeCategory 자동 감지 로직 디버깅 강화
This commit is contained in:
parent
5bf3c0fcd7
commit
289677a971
|
|
@ -144,6 +144,19 @@ export class TableManagementService {
|
||||||
logger.info(
|
logger.info(
|
||||||
`컬럼 정보 캐시에서 조회: ${tableName}, ${cachedResult.columns.length}/${cachedResult.total}개`
|
`컬럼 정보 캐시에서 조회: ${tableName}, ${cachedResult.columns.length}/${cachedResult.total}개`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 디버깅: 캐시된 currency_code 확인
|
||||||
|
const cachedCurrency = cachedResult.columns.find(
|
||||||
|
(col: any) => col.columnName === "currency_code"
|
||||||
|
);
|
||||||
|
if (cachedCurrency) {
|
||||||
|
console.log(`💾 [캐시] currency_code:`, {
|
||||||
|
columnName: cachedCurrency.columnName,
|
||||||
|
inputType: cachedCurrency.inputType,
|
||||||
|
webType: cachedCurrency.webType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return cachedResult;
|
return cachedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,10 +178,6 @@ export class TableManagementService {
|
||||||
const offset = (page - 1) * size;
|
const offset = (page - 1) * size;
|
||||||
|
|
||||||
// 🔥 company_code가 있으면 table_type_columns 조인하여 회사별 inputType 가져오기
|
// 🔥 company_code가 있으면 table_type_columns 조인하여 회사별 inputType 가져오기
|
||||||
console.log(
|
|
||||||
`🔍 [getColumnList] 시작: table=${tableName}, company=${companyCode}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const rawColumns = companyCode
|
const rawColumns = companyCode
|
||||||
? await query<any>(
|
? await query<any>(
|
||||||
`SELECT
|
`SELECT
|
||||||
|
|
@ -256,22 +265,6 @@ export class TableManagementService {
|
||||||
[tableName, size, offset]
|
[tableName, size, offset]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 디버깅: currency_code 확인
|
|
||||||
const currencyCol = rawColumns.find(
|
|
||||||
(col: any) => col.columnName === "currency_code"
|
|
||||||
);
|
|
||||||
if (currencyCol) {
|
|
||||||
console.log(`🎯 [getColumnList] currency_code 원본 쿼리 결과:`, {
|
|
||||||
columnName: currencyCol.columnName,
|
|
||||||
inputType: currencyCol.inputType,
|
|
||||||
ttc_input_type: currencyCol.ttc_input_type,
|
|
||||||
cl_input_type: currencyCol.cl_input_type,
|
|
||||||
webType: currencyCol.webType,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log(`⚠️ [getColumnList] currency_code가 rawColumns에 없음`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🆕 category_column_mapping 조회
|
// 🆕 category_column_mapping 조회
|
||||||
const tableExistsResult = await query<any>(
|
const tableExistsResult = await query<any>(
|
||||||
`SELECT EXISTS (
|
`SELECT EXISTS (
|
||||||
|
|
@ -804,8 +797,13 @@ export class TableManagementService {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 🔥 캐시 무효화: 해당 테이블의 컬럼 캐시 삭제
|
||||||
|
const cacheKeyPattern = `${CacheKeys.TABLE_COLUMNS(tableName, 1, 1000)}_${companyCode}`;
|
||||||
|
cache.delete(cacheKeyPattern);
|
||||||
|
cache.delete(CacheKeys.TABLE_COLUMN_COUNT(tableName));
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`컬럼 입력 타입 설정 완료: ${tableName}.${columnName} = ${inputType}, company: ${companyCode}`
|
`컬럼 입력 타입 설정 완료: ${tableName}.${columnName} = ${inputType}, company: ${companyCode} (캐시 무효화 완료)`
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,22 @@ export const SelectedItemsDetailInputComponent: React.FC<SelectedItemsDetailInpu
|
||||||
// 🆕 필드에 codeCategory가 있으면 자동으로 옵션 로드
|
// 🆕 필드에 codeCategory가 있으면 자동으로 옵션 로드
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadCodeOptions = async () => {
|
const loadCodeOptions = async () => {
|
||||||
|
console.log("🔄 [loadCodeOptions] 시작:", {
|
||||||
|
additionalFields: componentConfig.additionalFields,
|
||||||
|
targetTable: componentConfig.targetTable,
|
||||||
|
});
|
||||||
|
|
||||||
// 🆕 code/category 타입 필드 + codeCategory가 있는 필드 모두 처리
|
// 🆕 code/category 타입 필드 + codeCategory가 있는 필드 모두 처리
|
||||||
const codeFields = componentConfig.additionalFields?.filter(
|
const codeFields = componentConfig.additionalFields?.filter(
|
||||||
(field) => field.inputType === "code" || field.inputType === "category"
|
(field) => field.inputType === "code" || field.inputType === "category"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!codeFields || codeFields.length === 0) return;
|
console.log("🔍 [loadCodeOptions] code/category 필드:", codeFields);
|
||||||
|
|
||||||
|
if (!codeFields || codeFields.length === 0) {
|
||||||
|
console.log("⚠️ [loadCodeOptions] code/category 타입 필드가 없습니다");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const newOptions: Record<string, Array<{ label: string; value: string }>> = { ...codeOptions };
|
const newOptions: Record<string, Array<{ label: string; value: string }>> = { ...codeOptions };
|
||||||
|
|
||||||
|
|
@ -338,15 +348,17 @@ export const SelectedItemsDetailInputComponent: React.FC<SelectedItemsDetailInpu
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{categoryOptions && categoryOptions.length > 0 ? (
|
{categoryOptions && categoryOptions.length > 0 ? (
|
||||||
categoryOptions.map((option) => (
|
categoryOptions
|
||||||
<SelectItem key={option.value} value={option.value}>
|
.filter((option) => option.value !== "")
|
||||||
{option.label}
|
.map((option) => (
|
||||||
</SelectItem>
|
<SelectItem key={option.value} value={option.value}>
|
||||||
))
|
{option.label}
|
||||||
|
</SelectItem>
|
||||||
|
))
|
||||||
) : (
|
) : (
|
||||||
<SelectItem value="" disabled>
|
<div className="py-6 text-center text-xs text-muted-foreground">
|
||||||
옵션 로딩 중...
|
옵션 로딩 중...
|
||||||
</SelectItem>
|
</div>
|
||||||
)}
|
)}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
@ -374,7 +386,7 @@ export const SelectedItemsDetailInputComponent: React.FC<SelectedItemsDetailInpu
|
||||||
<SelectValue placeholder={field.placeholder || "선택하세요"} />
|
<SelectValue placeholder={field.placeholder || "선택하세요"} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{field.options?.map((option) => (
|
{field.options?.filter((option) => option.value !== "").map((option) => (
|
||||||
<SelectItem key={option.value} value={option.value}>
|
<SelectItem key={option.value} value={option.value}>
|
||||||
{option.label}
|
{option.label}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,7 @@ export const DynamicComponentConfigPanel: React.FC<ComponentConfigPanelProps> =
|
||||||
columnName: col.columnName || col.column_name,
|
columnName: col.columnName || col.column_name,
|
||||||
columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
|
columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
|
||||||
dataType: col.dataType || col.data_type || col.dbType,
|
dataType: col.dataType || col.data_type || col.dbType,
|
||||||
|
inputType: col.inputType || col.input_type, // 🆕 inputType 추가
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log("✅ 원본 테이블 컬럼 초기 로드 완료:", columns.length);
|
console.log("✅ 원본 테이블 컬럼 초기 로드 완료:", columns.length);
|
||||||
|
|
@ -238,6 +239,8 @@ export const DynamicComponentConfigPanel: React.FC<ComponentConfigPanelProps> =
|
||||||
columnName: col.columnName || col.column_name,
|
columnName: col.columnName || col.column_name,
|
||||||
columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
|
columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
|
||||||
dataType: col.dataType || col.data_type || col.dbType,
|
dataType: col.dataType || col.data_type || col.dbType,
|
||||||
|
inputType: col.inputType || col.input_type, // 🆕 inputType 추가
|
||||||
|
codeCategory: col.codeCategory || col.code_category, // 🆕 codeCategory 추가
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log("✅ 대상 테이블 컬럼 초기 로드 완료:", columns.length);
|
console.log("✅ 대상 테이블 컬럼 초기 로드 완료:", columns.length);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue