fix(rolesList): 권한관리 viewport 안에 맞도록 높이 조정

페이지 외부 컨테이너를 h-screen 으로 가두고, 상단 4분할 카드는
viewport 비례(clamp 220~320px), 하단 메뉴 트리는 남은 공간을
flex-1 + min-h-0 으로 채우되 max-h(clamp 280~430px) 로 상한 제한.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hjjeong
2026-05-11 18:13:22 +09:00
parent 4b97448467
commit 1bd0fd8b80
@@ -592,19 +592,21 @@ export default function RolesPage() {
} }
return ( return (
<div className="flex min-h-screen flex-col bg-background"> <div className="flex h-screen flex-col overflow-hidden bg-background">
<div className="w-full space-y-3 p-6"> <div className="flex w-full flex-1 flex-col space-y-3 overflow-hidden p-6">
<div className="space-y-1 border-b pb-3"> <div className="shrink-0 space-y-1 border-b pb-3">
<h1 className="text-xl font-bold tracking-tight"> </h1> <h1 className="text-xl font-bold tracking-tight"> </h1>
<p className="text-muted-foreground text-xs"> <p className="text-muted-foreground text-xs">
/ , . / , .
</p> </p>
</div> </div>
<CrossTenantBanner meta={crossTenantMeta} /> <div className="shrink-0">
<CrossTenantBanner meta={crossTenantMeta} />
</div>
{error && ( {error && (
<div className="border-destructive/50 bg-destructive/10 rounded-lg border p-3"> <div className="border-destructive/50 bg-destructive/10 shrink-0 rounded-lg border p-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<p className="text-destructive text-sm font-semibold">{error}</p> <p className="text-destructive text-sm font-semibold">{error}</p>
<button onClick={() => setError(null)} className="text-destructive"> <button onClick={() => setError(null)} className="text-destructive">
@@ -615,7 +617,7 @@ export default function RolesPage() {
)} )}
{/* 상단 4분할: 권한목록 | 권한있는직원 | 이동버튼 | 권한없는직원 */} {/* 상단 4분할: 권한목록 | 권한있는직원 | 이동버튼 | 권한없는직원 */}
<div className="grid grid-cols-1 gap-4 xl:grid-cols-[260px_1fr_auto_1fr]"> <div className="grid shrink-0 grid-cols-1 gap-4 xl:grid-cols-[260px_1fr_auto_1fr]">
{/* 권한 목록 */} {/* 권한 목록 */}
<div className="bg-card flex flex-col rounded-lg border shadow-sm"> <div className="bg-card flex flex-col rounded-lg border shadow-sm">
<div className="flex items-center justify-between border-b p-3"> <div className="flex items-center justify-between border-b p-3">
@@ -657,7 +659,10 @@ export default function RolesPage() {
</div> </div>
)} )}
</div> </div>
<div className="flex-1 overflow-y-auto" style={{ maxHeight: "440px" }}> <div
className="flex-1 overflow-y-auto"
style={{ maxHeight: "clamp(220px, 32vh, 320px)" }}
>
{isLoading ? ( {isLoading ? (
<div className="flex h-32 items-center justify-center"> <div className="flex h-32 items-center justify-center">
<div className="border-primary h-5 w-5 animate-spin rounded-full border-2 border-t-transparent" /> <div className="border-primary h-5 w-5 animate-spin rounded-full border-2 border-t-transparent" />
@@ -760,7 +765,10 @@ export default function RolesPage() {
</div> </div>
</div> </div>
</div> </div>
<div className="flex-1 overflow-y-auto" style={{ height: "380px" }}> <div
className="flex-1 overflow-y-auto"
style={{ height: "clamp(220px, 32vh, 320px)" }}
>
{!selectedRole ? ( {!selectedRole ? (
<div className="flex h-full items-center justify-center"> <div className="flex h-full items-center justify-center">
<p className="text-muted-foreground text-xs"> </p> <p className="text-muted-foreground text-xs"> </p>
@@ -857,7 +865,10 @@ export default function RolesPage() {
</div> </div>
</div> </div>
</div> </div>
<div className="flex-1 overflow-y-auto" style={{ height: "380px" }}> <div
className="flex-1 overflow-y-auto"
style={{ height: "clamp(220px, 32vh, 320px)" }}
>
{!selectedRole ? ( {!selectedRole ? (
<div className="flex h-full items-center justify-center"> <div className="flex h-full items-center justify-center">
<p className="text-muted-foreground text-xs"> </p> <p className="text-muted-foreground text-xs"> </p>
@@ -903,8 +914,11 @@ export default function RolesPage() {
</div> </div>
{/* 하단: 메뉴 권한 트리 (등록/수정, 삭제, 조회 3컬럼) */} {/* 하단: 메뉴 권한 트리 (등록/수정, 삭제, 조회 3컬럼) */}
<div className="bg-card rounded-lg border shadow-sm"> <div
<div className="border-b p-3"> className="bg-card flex min-h-0 flex-1 flex-col rounded-lg border shadow-sm"
style={{ maxHeight: "clamp(280px, 40vh, 430px)" }}
>
<div className="shrink-0 border-b p-3">
<h2 className="text-sm font-semibold"> <h2 className="text-sm font-semibold">
{" "} {" "}
{selectedRole && ( {selectedRole && (
@@ -916,19 +930,19 @@ export default function RolesPage() {
</p> </p>
</div> </div>
{!selectedRole ? ( {!selectedRole ? (
<div className="flex h-40 items-center justify-center"> <div className="flex flex-1 items-center justify-center">
<p className="text-muted-foreground text-sm"> </p> <p className="text-muted-foreground text-sm"> </p>
</div> </div>
) : isLoadingWorkspace ? ( ) : isLoadingWorkspace ? (
<div className="flex h-40 items-center justify-center"> <div className="flex flex-1 items-center justify-center">
<div className="border-primary h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" /> <div className="border-primary h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" />
</div> </div>
) : menuTree.length === 0 ? ( ) : menuTree.length === 0 ? (
<p className="text-muted-foreground p-12 text-center text-sm"> <div className="flex flex-1 items-center justify-center">
<p className="text-muted-foreground text-sm"> </p>
</p> </div>
) : ( ) : (
<div className="overflow-x-auto overflow-y-auto" style={{ maxHeight: "calc(100vh - 32rem)" }}> <div className="min-h-0 flex-1 overflow-auto">
<table className="w-full text-sm"> <table className="w-full text-sm">
<thead className="bg-muted sticky top-0 z-10"> <thead className="bg-muted sticky top-0 z-10">
<tr> <tr>