fix(pop): POP 화면 관리 좌측 패널 UX 개선 (스크롤 + 접기/펼치기)
- 좌측 패널 스크롤 수정: 부모에 overflow-hidden, ScrollArea에 min-h-0 추가하여 미분류 목록이 많을 때 스크롤바가 정상 작동하도록 개선 - 카테고리 그룹 기본 접힌 상태: loadGroups 자동 확장 로직 제거하여 페이지 진입 시 깔끔한 트리 뷰 제공 - 미분류 회사코드별 접기/펼치기: 최고관리자/COMPANY_7 등 회사코드 그룹마다 토글 헤더 추가, 항목 수 Badge 표시
This commit is contained in:
parent
ce5c2426b5
commit
15e22ba401
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
)}
|
||||
{grouped[companyCode].map((screen) => (
|
||||
<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" />
|
||||
)}
|
||||
<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>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in New Issue