커밋
This commit is contained in:
@@ -49,25 +49,33 @@ export const CategoryValueManager: React.FC<CategoryValueManagerProps> = ({
|
||||
const [editingValue, setEditingValue] = useState<TableCategoryValue | null>(
|
||||
null
|
||||
);
|
||||
const [showInactive, setShowInactive] = useState(false); // 비활성 항목 표시 옵션 (기본: 숨김)
|
||||
|
||||
// 카테고리 값 로드
|
||||
useEffect(() => {
|
||||
loadCategoryValues();
|
||||
}, [tableName, columnName]);
|
||||
|
||||
// 검색 필터링
|
||||
// 검색 필터링 + 비활성 필터링
|
||||
useEffect(() => {
|
||||
let filtered = values;
|
||||
|
||||
// 비활성 항목 필터링 (기본: 활성만 표시, 체크하면 비활성도 표시)
|
||||
if (!showInactive) {
|
||||
filtered = filtered.filter((v) => v.isActive !== false);
|
||||
}
|
||||
|
||||
// 검색어 필터링
|
||||
if (searchQuery) {
|
||||
const filtered = values.filter(
|
||||
filtered = filtered.filter(
|
||||
(v) =>
|
||||
v.valueCode.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
v.valueLabel.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
);
|
||||
setFilteredValues(filtered);
|
||||
} else {
|
||||
setFilteredValues(values);
|
||||
}
|
||||
}, [searchQuery, values]);
|
||||
|
||||
setFilteredValues(filtered);
|
||||
}, [searchQuery, values, showInactive]);
|
||||
|
||||
const loadCategoryValues = async () => {
|
||||
setIsLoading(true);
|
||||
@@ -264,10 +272,27 @@ export const CategoryValueManager: React.FC<CategoryValueManagerProps> = ({
|
||||
총 {filteredValues.length}개 항목
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={() => setIsAddDialogOpen(true)} size="sm">
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
새 값 추가
|
||||
</Button>
|
||||
<div className="flex items-center gap-3">
|
||||
{/* 비활성 항목 표시 옵션 */}
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
id="show-inactive"
|
||||
checked={showInactive}
|
||||
onCheckedChange={(checked) => setShowInactive(checked as boolean)}
|
||||
/>
|
||||
<label
|
||||
htmlFor="show-inactive"
|
||||
className="text-sm text-muted-foreground cursor-pointer whitespace-nowrap"
|
||||
>
|
||||
비활성 항목 표시
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<Button onClick={() => setIsAddDialogOpen(true)} size="sm">
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
새 값 추가
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 검색바 */}
|
||||
@@ -294,73 +319,90 @@ export const CategoryValueManager: React.FC<CategoryValueManagerProps> = ({
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{filteredValues.map((value) => (
|
||||
<div
|
||||
key={value.valueId}
|
||||
className="flex items-center gap-3 rounded-md border bg-card p-3 transition-colors hover:bg-accent"
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedValueIds.includes(value.valueId!)}
|
||||
onCheckedChange={() => handleSelectValue(value.valueId!)}
|
||||
/>
|
||||
|
||||
<div className="flex flex-1 items-center gap-2">
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{value.valueCode}
|
||||
</Badge>
|
||||
<span className="text-sm font-medium">
|
||||
{value.valueLabel}
|
||||
</span>
|
||||
{value.description && (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
- {value.description}
|
||||
</span>
|
||||
)}
|
||||
{value.isDefault && (
|
||||
<Badge variant="secondary" className="text-[10px]">
|
||||
기본값
|
||||
</Badge>
|
||||
)}
|
||||
{value.color && (
|
||||
<div
|
||||
className="h-4 w-4 rounded-full border"
|
||||
style={{ backgroundColor: value.color }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
checked={value.isActive !== false}
|
||||
onCheckedChange={() =>
|
||||
handleToggleActive(
|
||||
value.valueId!,
|
||||
value.isActive !== false
|
||||
)
|
||||
}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
{filteredValues.map((value) => {
|
||||
const isInactive = value.isActive === false;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={value.valueId}
|
||||
className={`flex items-center gap-3 rounded-md border bg-card p-3 transition-colors hover:bg-accent ${
|
||||
isInactive ? "opacity-50" : ""
|
||||
}`}
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedValueIds.includes(value.valueId!)}
|
||||
onCheckedChange={() => handleSelectValue(value.valueId!)}
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setEditingValue(value)}
|
||||
className="h-8 w-8"
|
||||
>
|
||||
<Edit2 className="h-3 w-3" />
|
||||
</Button>
|
||||
<div className="flex flex-1 items-center gap-2">
|
||||
{/* 색상 표시 (앞쪽으로 이동) */}
|
||||
{value.color && (
|
||||
<div
|
||||
className="h-4 w-4 rounded-full border flex-shrink-0"
|
||||
style={{ backgroundColor: value.color }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 라벨 */}
|
||||
<span className={`text-sm font-medium ${isInactive ? "line-through" : ""}`}>
|
||||
{value.valueLabel}
|
||||
</span>
|
||||
|
||||
{/* 설명 */}
|
||||
{value.description && (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
- {value.description}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* 기본값 배지 */}
|
||||
{value.isDefault && (
|
||||
<Badge variant="secondary" className="text-[10px]">
|
||||
기본값
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
{/* 비활성 배지 */}
|
||||
{isInactive && (
|
||||
<Badge variant="outline" className="text-[10px] text-muted-foreground">
|
||||
비활성
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => handleDeleteValue(value.valueId!)}
|
||||
className="h-8 w-8 text-destructive"
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
checked={value.isActive !== false}
|
||||
onCheckedChange={() =>
|
||||
handleToggleActive(
|
||||
value.valueId!,
|
||||
value.isActive !== false
|
||||
)
|
||||
}
|
||||
className="data-[state=checked]:bg-emerald-500"
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setEditingValue(value)}
|
||||
className="h-8 w-8"
|
||||
>
|
||||
<Edit2 className="h-3 w-3" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => handleDeleteValue(value.valueId!)}
|
||||
className="h-8 w-8 text-destructive"
|
||||
>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user