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:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user