forked from baron/baron-sso
Implement tenant import and RP auto login policies
This commit is contained in:
@@ -3,7 +3,6 @@ import type { AxiosError } from "axios";
|
||||
import { Building2, Sparkles } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Badge } from "../../../components/ui/badge";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
@@ -17,6 +16,11 @@ import { Label } from "../../../components/ui/label";
|
||||
import { Textarea } from "../../../components/ui/textarea";
|
||||
import { createTenant, fetchTenants } from "../../../lib/adminApi";
|
||||
import { t } from "../../../lib/i18n";
|
||||
import { DomainTagInput } from "../components/DomainTagInput";
|
||||
import {
|
||||
formatDomainConflictMessage,
|
||||
type ServerDomainConflict,
|
||||
} from "../utils/domainTags";
|
||||
|
||||
function TenantCreatePage() {
|
||||
const navigate = useNavigate();
|
||||
@@ -26,7 +30,10 @@ function TenantCreatePage() {
|
||||
const [parentId, setParentId] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [status, setStatus] = useState("active");
|
||||
const [domains, setDomains] = useState("");
|
||||
const [domains, setDomains] = useState<string[]>([]);
|
||||
const [forceDomainConflicts, setForceDomainConflicts] = useState<string[]>(
|
||||
[],
|
||||
);
|
||||
|
||||
const parentQuery = useQuery({
|
||||
queryKey: ["tenants", { limit: 1000 }],
|
||||
@@ -34,7 +41,7 @@ function TenantCreatePage() {
|
||||
});
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: () =>
|
||||
mutationFn: (overrideForceDomains?: string[]) =>
|
||||
createTenant({
|
||||
name,
|
||||
type,
|
||||
@@ -42,14 +49,34 @@ function TenantCreatePage() {
|
||||
parentId: parentId || undefined,
|
||||
description: description || undefined,
|
||||
status,
|
||||
domains: domains
|
||||
.split(",")
|
||||
.map((d) => d.trim())
|
||||
.filter((d) => d !== ""),
|
||||
domains,
|
||||
forceDomainConflicts: overrideForceDomains ?? forceDomainConflicts,
|
||||
}),
|
||||
onSuccess: () => {
|
||||
navigate("/tenants");
|
||||
},
|
||||
onError: (
|
||||
err: AxiosError<{
|
||||
code?: string;
|
||||
error?: string;
|
||||
conflicts?: ServerDomainConflict[];
|
||||
}>,
|
||||
) => {
|
||||
const conflicts = err.response?.data?.conflicts ?? [];
|
||||
if (
|
||||
err.response?.data?.code === "tenant_domain_conflict" &&
|
||||
conflicts.length > 0
|
||||
) {
|
||||
const nextForceDomains = Array.from(
|
||||
new Set([...forceDomainConflicts, ...conflicts.map((c) => c.domain)]),
|
||||
);
|
||||
const message = conflicts.map(formatDomainConflictMessage).join("\n");
|
||||
if (window.confirm(message)) {
|
||||
setForceDomainConflicts(nextForceDomains);
|
||||
mutation.mutate(nextForceDomains);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const errorMsg = (mutation.error as AxiosError<{ error?: string }>)?.response
|
||||
@@ -195,11 +222,13 @@ function TenantCreatePage() {
|
||||
"허용된 도메인 (콤마로 구분)",
|
||||
)}
|
||||
</Label>
|
||||
<Input
|
||||
<DomainTagInput
|
||||
id="tenant-domains"
|
||||
name="domains"
|
||||
value={domains}
|
||||
onChange={(e) => setDomains(e.target.value)}
|
||||
onChange={setDomains}
|
||||
tenants={parentQuery.data?.items ?? []}
|
||||
confirmedConflicts={forceDomainConflicts}
|
||||
onConfirmedConflictsChange={setForceDomainConflicts}
|
||||
placeholder={t(
|
||||
"ui.admin.tenants.create.form.domains_placeholder",
|
||||
"example.com, example.kr",
|
||||
@@ -268,7 +297,7 @@ function TenantCreatePage() {
|
||||
{t("ui.common.cancel", "취소")}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => mutation.mutate()}
|
||||
onClick={() => mutation.mutate(undefined)}
|
||||
disabled={mutation.isPending || name.trim() === ""}
|
||||
>
|
||||
{t("ui.common.create", "생성")}
|
||||
|
||||
Reference in New Issue
Block a user