1
0
forked from baron/baron-sso

3단계 권한 모델 확장, keto 권한 정책

This commit is contained in:
2026-02-03 14:21:37 +09:00
parent 6dbdd5d483
commit d09abab5a2
24 changed files with 1071 additions and 141 deletions

View File

@@ -127,7 +127,18 @@ function TenantListPage() {
<TableCell>{tenant.slug}</TableCell>
<TableCell>
<Badge
variant={tenant.status === "active" ? "default" : "muted"}
variant={
tenant.status === "active"
? "default"
: tenant.status === "pending"
? "secondary"
: "muted"
}
className={
tenant.status === "pending"
? "bg-yellow-100 text-yellow-800"
: ""
}
>
{tenant.status}
</Badge>

View File

@@ -1,4 +1,4 @@
import { useMutation, useQuery } from "@tanstack/react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { Save, Trash2 } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
@@ -15,6 +15,7 @@ import { Input } from "../../../components/ui/input";
import { Label } from "../../../components/ui/label";
import { Textarea } from "../../../components/ui/textarea";
import {
approveTenant,
deleteTenant,
fetchTenant,
updateTenant,
@@ -23,6 +24,7 @@ import {
export function TenantProfilePage() {
const { tenantId } = useParams<{ tenantId: string }>();
const navigate = useNavigate();
const queryClient = useQueryClient();
if (!tenantId) {
return <div>Tenant ID is missing</div>;
@@ -62,7 +64,18 @@ export function TenantProfilePage() {
.filter((d) => d !== ""),
}),
onSuccess: () => {
navigate("/tenants");
queryClient.invalidateQueries({ queryKey: ["tenants"] });
queryClient.invalidateQueries({ queryKey: ["tenant", tenantId] });
alert("Tenant updated successfully");
},
});
const approveMutation = useMutation({
mutationFn: () => approveTenant(tenantId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["tenants"] });
queryClient.invalidateQueries({ queryKey: ["tenant", tenantId] });
alert("Tenant approved successfully");
},
});
@@ -84,6 +97,12 @@ export function TenantProfilePage() {
}
};
const handleApprove = () => {
if (window.confirm("Approve this tenant?")) {
approveMutation.mutate();
}
};
return (
<>
<Card className="bg-[var(--color-panel)] mt-6">
@@ -168,6 +187,16 @@ export function TenantProfilePage() {
Delete
</Button>
<div className="flex items-center gap-2">
{status === "pending" && (
<Button
variant="default"
className="bg-green-600 hover:bg-green-700"
onClick={handleApprove}
disabled={approveMutation.isPending}
>
Approve Tenant
</Button>
)}
<Button variant="outline" onClick={() => navigate("/tenants")}>
Cancel
</Button>