feat: 테이블 리스트에서 카테고리 다중 값 배지 표시 지원

문제:
- 테이블에서 'CATEGORY_218152,CATEGORY_205381' 같은 다중 값이
- 배지로 표시되지 않고 코드값 그대로 보임

원인:
- formatCellValue의 카테고리 렌더링이 단일 값만 처리
- 콤마로 구분된 다중 값 파싱 로직 없음

해결:
1. 콤마 구분자 감지 및 값 배열로 분리
2. 단일 값: 기존 로직 유지 (단일 배지)
3. 다중 값: flex-wrap gap-1로 여러 배지 렌더링
4. 각 배지는 매핑된 라벨과 색상 사용

결과:
 다중선택 저장된 데이터가 테이블에서 여러 배지로 표시됨
 각 배지에 올바른 색상과 라벨 적용
 단일 값도 기존처럼 정상 작동
This commit is contained in:
kjs 2025-11-21 10:03:26 +09:00
parent f4d27f51a3
commit bb49073bf7
2 changed files with 90 additions and 25 deletions

View File

@ -207,14 +207,39 @@ const SelectBasicComponent: React.FC<SelectBasicComponentProps> = ({
// 외부 value prop 변경 시 selectedValue 업데이트
useEffect(() => {
const newValue = externalValue || config?.value || "";
// 값이 실제로 다른 경우에만 업데이트 (빈 문자열도 유효한 값으로 처리)
if (newValue !== selectedValue) {
setSelectedValue(newValue);
// 다중선택 모드인 경우 selectedValues도 업데이트
if (isMultiple && typeof newValue === "string" && newValue) {
console.log("🔍 [SelectBasic] 외부 값 변경 감지:", {
componentId: component.id,
columnName: (component as any).columnName,
isMultiple,
newValue,
selectedValue,
selectedValues,
externalValue,
"config.value": config?.value,
});
// 다중선택 모드인 경우
if (isMultiple) {
if (typeof newValue === "string" && newValue) {
const values = newValue.split(",").map(v => v.trim()).filter(v => v);
setSelectedValues(values);
const currentValuesStr = selectedValues.join(",");
if (newValue !== currentValuesStr) {
console.log("✅ [SelectBasic] 다중선택 값 업데이트:", {
from: selectedValues,
to: values,
});
setSelectedValues(values);
}
} else if (!newValue && selectedValues.length > 0) {
console.log("✅ [SelectBasic] 다중선택 값 초기화");
setSelectedValues([]);
}
} else {
// 단일선택 모드인 경우
if (newValue !== selectedValue) {
setSelectedValue(newValue);
}
}
}, [externalValue, config?.value, isMultiple]);

View File

@ -1425,33 +1425,73 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
);
}
// 카테고리 타입: 배지로 표시 (배지 없음 옵션 지원)
// 카테고리 타입: 배지로 표시 (배지 없음 옵션 지원, 다중 값 지원)
if (inputType === "category") {
if (!value) return "";
const mapping = categoryMappings[column.columnName];
const categoryData = mapping?.[String(value)];
const { Badge } = require("@/components/ui/badge");
// 매핑 데이터가 있으면 라벨과 색상 사용, 없으면 코드값과 기본색상
const displayLabel = categoryData?.label || String(value);
const displayColor = categoryData?.color || "#64748b"; // 기본 slate 색상
// 다중 값 처리: 콤마로 구분된 값들을 분리
const valueStr = String(value);
const values = valueStr.includes(",")
? valueStr.split(",").map(v => v.trim()).filter(v => v)
: [valueStr];
// 배지 없음 옵션: color가 "none"이면 텍스트만 표시
if (displayColor === "none") {
return <span className="text-sm">{displayLabel}</span>;
// 단일 값인 경우 (기존 로직)
if (values.length === 1) {
const categoryData = mapping?.[values[0]];
const displayLabel = categoryData?.label || values[0];
const displayColor = categoryData?.color || "#64748b";
if (displayColor === "none") {
return <span className="text-sm">{displayLabel}</span>;
}
return (
<Badge
style={{
backgroundColor: displayColor,
borderColor: displayColor,
}}
className="text-white"
>
{displayLabel}
</Badge>
);
}
const { Badge } = require("@/components/ui/badge");
// 다중 값인 경우: 여러 배지 렌더링
return (
<Badge
style={{
backgroundColor: displayColor,
borderColor: displayColor,
}}
className="text-white"
>
{displayLabel}
</Badge>
<div className="flex flex-wrap gap-1">
{values.map((val, idx) => {
const categoryData = mapping?.[val];
const displayLabel = categoryData?.label || val;
const displayColor = categoryData?.color || "#64748b";
if (displayColor === "none") {
return (
<span key={idx} className="text-sm">
{displayLabel}
{idx < values.length - 1 && ", "}
</span>
);
}
return (
<Badge
key={idx}
style={{
backgroundColor: displayColor,
borderColor: displayColor,
}}
className="text-white"
>
{displayLabel}
</Badge>
);
})}
</div>
);
}