forked from baron/baron-sso
Merge branch 'dev' into feat/org-chart-rebac
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Building2, Plus, Users } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Badge } from "../../../components/ui/badge";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../components/ui/card";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../../components/ui/table";
|
||||
import {
|
||||
fetchGroups,
|
||||
fetchTenants,
|
||||
type TenantSummary,
|
||||
} from "../../../lib/adminApi";
|
||||
|
||||
export default function GlobalUserGroupListPage() {
|
||||
const { data: tenantList, isLoading: isTenantsLoading } = useQuery({
|
||||
queryKey: ["admin-tenants"],
|
||||
queryFn: () => fetchTenants(100, 0),
|
||||
});
|
||||
|
||||
if (isTenantsLoading)
|
||||
return <div className="p-8">Loading tenants and groups...</div>;
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<header className="flex items-start justify-between">
|
||||
<div className="space-y-1">
|
||||
<h2 className="text-3xl font-bold tracking-tight">User Groups</h2>
|
||||
<p className="text-muted-foreground">
|
||||
모든 테넌트의 유저 그룹을 관리합니다. 권한 상속의 주체가 되는 그룹을
|
||||
설정하세요.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="grid gap-6">
|
||||
{tenantList?.items.map((tenant) => (
|
||||
<TenantGroupCard key={tenant.id} tenant={tenant} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TenantGroupCard({ tenant }: { tenant: TenantSummary }) {
|
||||
const { data: groups, isLoading } = useQuery({
|
||||
queryKey: ["tenant-user-groups", tenant.id],
|
||||
queryFn: () => fetchGroups(tenant.id),
|
||||
});
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<div className="space-y-1">
|
||||
<CardTitle className="text-xl flex items-center gap-2">
|
||||
<Building2 size={20} className="text-muted-foreground" />
|
||||
{tenant.name}
|
||||
<Badge variant="outline" className="ml-2">
|
||||
{tenant.slug}
|
||||
</Badge>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
이 테넌트에 정의된 유저 그룹 목록입니다.
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Button size="sm" variant="outline" asChild>
|
||||
<Link to={`/tenants/${tenant.id}/user-groups`}>
|
||||
<Plus size={16} className="mr-2" />
|
||||
그룹 관리
|
||||
</Link>
|
||||
</Button>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[250px]">그룹명</TableHead>
|
||||
<TableHead>설명</TableHead>
|
||||
<TableHead className="w-[100px]">멤버 수</TableHead>
|
||||
<TableHead className="text-right">작업</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{isLoading ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="text-center">
|
||||
Loading...
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : groups?.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={4}
|
||||
className="text-center text-muted-foreground py-4"
|
||||
>
|
||||
등록된 유저 그룹이 없습니다.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
groups?.map((group) => (
|
||||
<TableRow key={group.id}>
|
||||
<TableCell className="font-medium">
|
||||
<div className="flex items-center gap-2">
|
||||
<Users size={14} className="text-primary" />
|
||||
<Link
|
||||
to={`/tenants/${tenant.id}/user-groups/${group.id}`}
|
||||
className="hover:underline"
|
||||
>
|
||||
{group.name}
|
||||
</Link>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{group.description || "-"}</TableCell>
|
||||
<TableCell>{group.members?.length || 0} 명</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<Button variant="ghost" size="sm" asChild>
|
||||
<Link
|
||||
to={`/tenants/${tenant.id}/user-groups/${group.id}`}
|
||||
>
|
||||
상세보기
|
||||
</Link>
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user