fix(pop): POP 화면 관리 좌측 패널 UX 개선 (스크롤 + 접기/펼치기)

- 좌측 패널 스크롤 수정: 부모에 overflow-hidden, ScrollArea에 min-h-0
  추가하여 미분류 목록이 많을 때 스크롤바가 정상 작동하도록 개선
- 카테고리 그룹 기본 접힌 상태: loadGroups 자동 확장 로직 제거하여
  페이지 진입 시 깔끔한 트리 뷰 제공
- 미분류 회사코드별 접기/펼치기: 최고관리자/COMPANY_7 등 회사코드
  그룹마다 토글 헤더 추가, 항목 수 Badge 표시
This commit is contained in:
SeongHyun Kim 2026-03-04 13:18:49 +09:00
parent ce5c2426b5
commit 15e22ba401
2 changed files with 43 additions and 21 deletions

View File

@ -285,7 +285,7 @@ export default function PopScreenManagementPage() {
) : (
<div className="flex-1 overflow-hidden flex">
{/* 왼쪽: 카테고리 트리 + 화면 목록 */}
<div className="w-[320px] min-w-[280px] max-w-[400px] flex flex-col border-r bg-background">
<div className="w-[320px] min-w-[280px] max-w-[400px] flex flex-col border-r bg-background overflow-hidden">
{/* 검색 */}
<div className="shrink-0 p-3 border-b">
<div className="relative">

View File

@ -499,6 +499,9 @@ export function PopCategoryTree({
const [movingFromGroupId, setMovingFromGroupId] = useState<number | null>(null);
const [moveSearchTerm, setMoveSearchTerm] = useState("");
// 미분류 회사코드별 접기/펼치기
const [expandedCompanyCodes, setExpandedCompanyCodes] = useState<Set<string>>(new Set());
// 화면 맵 생성 (screen_id로 빠르게 조회)
const screensMap = useMemo(() => {
const map = new Map<number, ScreenDefinition>();
@ -517,14 +520,6 @@ export function PopCategoryTree({
// 그룹 목록 조회
const data = await getPopScreenGroups(searchTerm);
setGroups(data);
// 첫 로드 시 루트 그룹들 자동 확장
if (expandedGroups.size === 0 && data.length > 0) {
const rootIds = data
.filter((g) => g.hierarchy_path === "POP" || g.hierarchy_path?.split("/").length === 2)
.map((g) => g.id);
setExpandedGroups(new Set(rootIds));
}
} catch (error) {
console.error("POP 그룹 로드 실패:", error);
toast.error("그룹 목록 로드에 실패했습니다.");
@ -934,7 +929,7 @@ export function PopCategoryTree({
}
return (
<div className="flex flex-col h-full">
<div className="flex flex-col h-full overflow-hidden">
{/* 헤더 */}
<div className="shrink-0 p-3 border-b flex items-center justify-between">
<h3 className="text-sm font-medium">POP </h3>
@ -949,7 +944,7 @@ export function PopCategoryTree({
</div>
{/* 트리 영역 */}
<ScrollArea className="flex-1">
<ScrollArea className="flex-1 min-h-0">
<div className="p-2">
{treeData.length === 0 && ungroupedScreens.length === 0 ? (
<div className="text-center text-sm text-muted-foreground py-8">
@ -1009,16 +1004,42 @@ export function PopCategoryTree({
return acc;
}, {});
const companyKeys = Object.keys(grouped).sort();
const hasMultipleCompanies = companyKeys.length > 1;
return companyKeys.map((companyCode) => (
const toggleCompanyCode = (code: string) => {
setExpandedCompanyCodes((prev) => {
const next = new Set(prev);
if (next.has(code)) {
next.delete(code);
} else {
next.add(code);
}
return next;
});
};
return companyKeys.map((companyCode) => {
const isExpanded = expandedCompanyCodes.has(companyCode);
const label = companyCode === "*" ? "최고관리자" : companyCode;
return (
<div key={`ungrouped-company-${companyCode}`}>
{hasMultipleCompanies && (
<div className="text-[10px] font-medium text-muted-foreground px-2 py-1 mt-1 bg-muted/50 rounded">
{companyCode === "*" ? "최고관리자" : companyCode}
</div>
<div
className="flex items-center gap-1 px-2 py-1 mt-1 bg-muted/50 rounded cursor-pointer select-none hover:bg-muted transition-colors"
onClick={() => toggleCompanyCode(companyCode)}
>
{isExpanded ? (
<ChevronDown className="h-3 w-3 text-muted-foreground shrink-0" />
) : (
<ChevronRight className="h-3 w-3 text-muted-foreground shrink-0" />
)}
{grouped[companyCode].map((screen) => (
<span className="text-[10px] font-medium text-muted-foreground">
{label}
</span>
<Badge variant="outline" className="ml-auto h-4 text-[9px] px-1">
{grouped[companyCode].length}
</Badge>
</div>
{isExpanded && grouped[companyCode].map((screen) => (
<div
key={`ungrouped-${screen.screenId}`}
className={cn(
@ -1027,7 +1048,7 @@ export function PopCategoryTree({
? "bg-primary/10 text-primary"
: "hover:bg-muted",
"group",
hasMultipleCompanies && "pl-4"
"pl-4"
)}
onClick={() => onScreenSelect(screen)}
onDoubleClick={() => onScreenDesign(screen)}
@ -1078,7 +1099,8 @@ export function PopCategoryTree({
</div>
))}
</div>
));
);
});
})()}
</div>
)}