forked from baron/baron-sso
feat: implement role-based UI filtering for overview and navigation
This commit is contained in:
@@ -52,9 +52,15 @@ function AppLayout() {
|
|||||||
const isTenantAdmin = profile?.role === "tenant_admin";
|
const isTenantAdmin = profile?.role === "tenant_admin";
|
||||||
const manageableCount = profile?.manageableTenants?.length ?? 0;
|
const manageableCount = profile?.manageableTenants?.length ?? 0;
|
||||||
|
|
||||||
|
// Filter out restricted items for non-super admins
|
||||||
|
const filteredItems = items.filter(item => {
|
||||||
|
if (item.to === "/api-keys") return isSuperAdmin;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (isSuperAdmin) {
|
if (isSuperAdmin) {
|
||||||
// Super Admin sees everything
|
// Super Admin sees everything
|
||||||
items.splice(1, 0, {
|
filteredItems.splice(1, 0, {
|
||||||
label: "ui.admin.nav.tenants",
|
label: "ui.admin.nav.tenants",
|
||||||
to: "/tenants",
|
to: "/tenants",
|
||||||
icon: Building2,
|
icon: Building2,
|
||||||
@@ -62,14 +68,14 @@ function AppLayout() {
|
|||||||
} else if (isTenantAdmin) {
|
} else if (isTenantAdmin) {
|
||||||
if (manageableCount <= 1 && profile?.tenantId) {
|
if (manageableCount <= 1 && profile?.tenantId) {
|
||||||
// Direct link if only one (or zero in array but has tenantId) tenant
|
// Direct link if only one (or zero in array but has tenantId) tenant
|
||||||
items.splice(1, 0, {
|
filteredItems.splice(1, 0, {
|
||||||
label: "ui.admin.nav.my_tenant",
|
label: "ui.admin.nav.my_tenant",
|
||||||
to: `/tenants/${profile.tenantId}`,
|
to: `/tenants/${profile.tenantId}`,
|
||||||
icon: Building2,
|
icon: Building2,
|
||||||
});
|
});
|
||||||
} else if (manageableCount > 1) {
|
} else if (manageableCount > 1) {
|
||||||
// Show list menu if multiple tenants
|
// Show list menu if multiple tenants
|
||||||
items.splice(1, 0, {
|
filteredItems.splice(1, 0, {
|
||||||
label: "ui.admin.nav.tenants",
|
label: "ui.admin.nav.tenants",
|
||||||
to: "/tenants",
|
to: "/tenants",
|
||||||
icon: Building2,
|
icon: Building2,
|
||||||
@@ -77,7 +83,7 @@ function AppLayout() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return filteredItems;
|
||||||
}, [profile]);
|
}, [profile]);
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
CardTitle,
|
CardTitle,
|
||||||
} from "../../components/ui/card";
|
} from "../../components/ui/card";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
|
import { RoleGuard } from "../../components/auth/RoleGuard";
|
||||||
import PermissionChecker from "./components/PermissionChecker";
|
import PermissionChecker from "./components/PermissionChecker";
|
||||||
|
|
||||||
const summaryCards = [
|
const summaryCards = [
|
||||||
@@ -178,16 +179,18 @@ function GlobalOverviewPage() {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-3">
|
<CardContent className="space-y-3">
|
||||||
<Button
|
<RoleGuard roles={["super_admin"]}>
|
||||||
asChild
|
<Button
|
||||||
className="w-full justify-between"
|
asChild
|
||||||
variant="outline"
|
className="w-full justify-between"
|
||||||
>
|
variant="outline"
|
||||||
<Link to="/tenants/new">
|
>
|
||||||
{t("ui.admin.overview.quick_links.add_tenant", "테넌트 추가")}
|
<Link to="/tenants/new">
|
||||||
<ArrowUpRight size={16} />
|
{t("ui.admin.overview.quick_links.add_tenant", "테넌트 추가")}
|
||||||
</Link>
|
<ArrowUpRight size={16} />
|
||||||
</Button>
|
</Link>
|
||||||
|
</Button>
|
||||||
|
</RoleGuard>
|
||||||
<Button
|
<Button
|
||||||
asChild
|
asChild
|
||||||
className="w-full justify-between"
|
className="w-full justify-between"
|
||||||
@@ -201,19 +204,21 @@ function GlobalOverviewPage() {
|
|||||||
<ArrowUpRight size={16} />
|
<ArrowUpRight size={16} />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<RoleGuard roles={["super_admin"]}>
|
||||||
asChild
|
<Button
|
||||||
className="w-full justify-between"
|
asChild
|
||||||
variant="outline"
|
className="w-full justify-between"
|
||||||
>
|
variant="outline"
|
||||||
<Link to="/api-keys">
|
>
|
||||||
{t(
|
<Link to="/api-keys">
|
||||||
"ui.admin.overview.quick_links.api_key_management",
|
{t(
|
||||||
"API 키 관리",
|
"ui.admin.overview.quick_links.api_key_management",
|
||||||
)}
|
"API 키 관리",
|
||||||
<ArrowUpRight size={16} />
|
)}
|
||||||
</Link>
|
<ArrowUpRight size={16} />
|
||||||
</Button>
|
</Link>
|
||||||
|
</Button>
|
||||||
|
</RoleGuard>
|
||||||
<Button
|
<Button
|
||||||
asChild
|
asChild
|
||||||
className="w-full justify-between"
|
className="w-full justify-between"
|
||||||
@@ -231,7 +236,9 @@ function GlobalOverviewPage() {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PermissionChecker />
|
<RoleGuard roles={["super_admin"]}>
|
||||||
|
<PermissionChecker />
|
||||||
|
</RoleGuard>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user