From 15e22ba401c3ddcf280f4610a454cbc2098d2297 Mon Sep 17 00:00:00 2001 From: SeongHyun Kim Date: Wed, 4 Mar 2026 13:18:49 +0900 Subject: [PATCH] =?UTF-8?q?fix(pop):=20POP=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EC=A2=8C=EC=B8=A1=20=ED=8C=A8=EB=84=90=20?= =?UTF-8?q?UX=20=EA=B0=9C=EC=84=A0=20(=EC=8A=A4=ED=81=AC=EB=A1=A4=20+=20?= =?UTF-8?q?=EC=A0=91=EA=B8=B0/=ED=8E=BC=EC=B9=98=EA=B8=B0)=20-=20=EC=A2=8C?= =?UTF-8?q?=EC=B8=A1=20=ED=8C=A8=EB=84=90=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EB=B6=80=EB=AA=A8=EC=97=90=20overflow-hi?= =?UTF-8?q?dden,=20ScrollArea=EC=97=90=20min-h-0=20=20=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=98=EC=97=AC=20=EB=AF=B8=EB=B6=84=EB=A5=98=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=EC=9D=B4=20=EB=A7=8E=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=EB=B0=94=EA=B0=80=20=EC=A0=95?= =?UTF-8?q?=EC=83=81=20=EC=9E=91=EB=8F=99=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20-=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC?= =?UTF-8?q?=20=EA=B7=B8=EB=A3=B9=20=EA=B8=B0=EB=B3=B8=20=EC=A0=91=ED=9E=8C?= =?UTF-8?q?=20=EC=83=81=ED=83=9C:=20loadGroups=20=EC=9E=90=EB=8F=99=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=20=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=A7=84=EC=9E=85=20=EC=8B=9C=20=EA=B9=94=EB=81=94=ED=95=9C=20?= =?UTF-8?q?=ED=8A=B8=EB=A6=AC=20=EB=B7=B0=20=EC=A0=9C=EA=B3=B5=20-=20?= =?UTF-8?q?=EB=AF=B8=EB=B6=84=EB=A5=98=20=ED=9A=8C=EC=82=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=B3=84=20=EC=A0=91=EA=B8=B0/=ED=8E=BC=EC=B9=98?= =?UTF-8?q?=EA=B8=B0:=20=EC=B5=9C=EA=B3=A0=EA=B4=80=EB=A6=AC=EC=9E=90/COMP?= =?UTF-8?q?ANY=5F7=20=EB=93=B1=20=ED=9A=8C=EC=82=AC=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=20=20=EA=B7=B8=EB=A3=B9=EB=A7=88=EB=8B=A4=20=ED=86=A0=EA=B8=80?= =?UTF-8?q?=20=ED=97=A4=EB=8D=94=20=EC=B6=94=EA=B0=80,=20=ED=95=AD?= =?UTF-8?q?=EB=AA=A9=20=EC=88=98=20Badge=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/screenMng/popScreenMngList/page.tsx | 2 +- .../pop/management/PopCategoryTree.tsx | 62 +++++++++++++------ 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/frontend/app/(main)/admin/screenMng/popScreenMngList/page.tsx b/frontend/app/(main)/admin/screenMng/popScreenMngList/page.tsx index d8c10cf6..aec81bb4 100644 --- a/frontend/app/(main)/admin/screenMng/popScreenMngList/page.tsx +++ b/frontend/app/(main)/admin/screenMng/popScreenMngList/page.tsx @@ -285,7 +285,7 @@ export default function PopScreenManagementPage() { ) : (
{/* 왼쪽: 카테고리 트리 + 화면 목록 */} -
+
{/* 검색 */}
diff --git a/frontend/components/pop/management/PopCategoryTree.tsx b/frontend/components/pop/management/PopCategoryTree.tsx index 3ad767e1..705d7163 100644 --- a/frontend/components/pop/management/PopCategoryTree.tsx +++ b/frontend/components/pop/management/PopCategoryTree.tsx @@ -499,6 +499,9 @@ export function PopCategoryTree({ const [movingFromGroupId, setMovingFromGroupId] = useState(null); const [moveSearchTerm, setMoveSearchTerm] = useState(""); + // 미분류 회사코드별 접기/펼치기 + const [expandedCompanyCodes, setExpandedCompanyCodes] = useState>(new Set()); + // 화면 맵 생성 (screen_id로 빠르게 조회) const screensMap = useMemo(() => { const map = new Map(); @@ -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 ( -
+
{/* 헤더 */}

POP 카테고리

@@ -949,7 +944,7 @@ export function PopCategoryTree({
{/* 트리 영역 */} - +
{treeData.length === 0 && ungroupedScreens.length === 0 ? (
@@ -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 (
- {hasMultipleCompanies && ( -
- {companyCode === "*" ? "최고관리자" : companyCode} -
- )} - {grouped[companyCode].map((screen) => ( +
toggleCompanyCode(companyCode)} + > + {isExpanded ? ( + + ) : ( + + )} + + {label} + + + {grouped[companyCode].length} + +
+ {isExpanded && grouped[companyCode].map((screen) => (
onScreenSelect(screen)} onDoubleClick={() => onScreenDesign(screen)} @@ -1078,7 +1099,8 @@ export function PopCategoryTree({
))}
- )); + ); + }); })()}
)}