diff --git a/adminfront/src/components/ui/use-toast.ts b/adminfront/src/components/ui/use-toast.ts
index adbc7f38..402ed87c 100644
--- a/adminfront/src/components/ui/use-toast.ts
+++ b/adminfront/src/components/ui/use-toast.ts
@@ -30,20 +30,26 @@ const toastBase = (message: string, type: ToastType = "success") => {
export const toast = Object.assign(toastBase, {
success: (message: string, options?: { description?: string }) => {
- const finalMessage = options?.description ? `${message}
-${options.description}` : message;
+ const finalMessage = options?.description
+ ? `${message}
+${options.description}`
+ : message;
toastBase(finalMessage, "success");
},
error: (message: string, options?: { description?: string }) => {
- const finalMessage = options?.description ? `${message}
-${options.description}` : message;
+ const finalMessage = options?.description
+ ? `${message}
+${options.description}`
+ : message;
toastBase(finalMessage, "error");
},
info: (message: string, options?: { description?: string }) => {
- const finalMessage = options?.description ? `${message}
-${options.description}` : message;
+ const finalMessage = options?.description
+ ? `${message}
+${options.description}`
+ : message;
toastBase(finalMessage, "info");
- }
+ },
});
export const useToastState = () => {
diff --git a/adminfront/src/features/tenants/components/OrgChartUploadModal.tsx b/adminfront/src/features/tenants/components/OrgChartUploadModal.tsx
index 1a993c18..551c13dc 100644
--- a/adminfront/src/features/tenants/components/OrgChartUploadModal.tsx
+++ b/adminfront/src/features/tenants/components/OrgChartUploadModal.tsx
@@ -2,7 +2,6 @@ import { useMutation } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { Download, FileText, Loader2, Upload } from "lucide-react";
import * as React from "react";
-import { toast } from "../../../components/ui/use-toast";
import { Button } from "../../../components/ui/button";
import {
Dialog,
@@ -13,6 +12,7 @@ import {
DialogTitle,
DialogTrigger,
} from "../../../components/ui/dialog";
+import { toast } from "../../../components/ui/use-toast";
import { importOrgChart } from "../../../lib/adminApi";
import { t } from "../../../lib/i18n";
diff --git a/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx b/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx
index 5186823c..4031f590 100644
--- a/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx
+++ b/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx
@@ -12,7 +12,6 @@ import {
import { useState } from "react";
import { useAuth } from "react-oidc-context";
import { useParams } from "react-router-dom";
-import { toast } from "../../../components/ui/use-toast";
import { Badge } from "../../../components/ui/badge";
import { Button } from "../../../components/ui/button";
import {
@@ -39,6 +38,7 @@ import {
TableHeader,
TableRow,
} from "../../../components/ui/table";
+import { toast } from "../../../components/ui/use-toast";
import {
addTenantAdmin,
addTenantOwner,
@@ -291,25 +291,29 @@ export function TenantAdminsAndOwnersTab() {
{owner.email}
-
+ )}
+
+
))
@@ -420,25 +422,29 @@ export function TenantAdminsAndOwnersTab() {
{admin.email}
-
- handleRemoveAdmin(admin.id, admin.name)
- }
- disabled={
- removeAdminMutation.isPending ||
- admin.id === currentUserId ||
- currentAdmins.length <= 1
- }
- title={
- admin.id === currentUserId
+
+
+ handleRemoveAdmin(admin.id, admin.name)
+ }
+ disabled={
+ removeAdminMutation.isPending ||
+ admin.id === currentUserId ||
+ currentAdmins.length <= 1
+ }
+ >
+
+
+
+ {admin.id === currentUserId
? t(
"msg.admin.tenants.admins.remove_self",
"본인의 권한은 회수할 수 없습니다.",
@@ -451,11 +457,9 @@ export function TenantAdminsAndOwnersTab() {
: t(
"ui.admin.tenants.admins.remove_title",
"관리자 권한 회수",
- )
- }
- >
-
-
+ )}
+
+
))
diff --git a/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx b/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx
index 6d56c737..2778c8e8 100644
--- a/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx
+++ b/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx
@@ -18,7 +18,6 @@ import {
import type React from "react";
import { useState } from "react";
import { useParams } from "react-router-dom";
-import { toast } from "../../../components/ui/use-toast";
import { Badge } from "../../../components/ui/badge";
import { Button } from "../../../components/ui/button";
import {
@@ -38,6 +37,7 @@ import {
TableHeader,
TableRow,
} from "../../../components/ui/table";
+import { toast } from "../../../components/ui/use-toast";
import {
type GroupSummary,
addGroupMember,
diff --git a/adminfront/src/features/tenants/routes/TenantProfilePage.tsx b/adminfront/src/features/tenants/routes/TenantProfilePage.tsx
index 17b787c3..6d186c62 100644
--- a/adminfront/src/features/tenants/routes/TenantProfilePage.tsx
+++ b/adminfront/src/features/tenants/routes/TenantProfilePage.tsx
@@ -3,7 +3,6 @@ import type { AxiosError } from "axios";
import { Save, Trash2 } from "lucide-react";
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
-import { toast } from "../../../components/ui/use-toast";
import { Button } from "../../../components/ui/button";
import {
Card,
@@ -15,10 +14,12 @@ import {
import { Input } from "../../../components/ui/input";
import { Label } from "../../../components/ui/label";
import { Textarea } from "../../../components/ui/textarea";
+import { toast } from "../../../components/ui/use-toast";
import {
approveTenant,
deleteTenant,
fetchTenant,
+ fetchTenants,
updateTenant,
} from "../../../lib/adminApi";
import { t } from "../../../lib/i18n";
@@ -39,12 +40,21 @@ export function TenantProfilePage() {
queryFn: () => fetchTenant(tenantId),
});
+ const parentQuery = useQuery({
+ queryKey: ["tenants", "list-all"],
+ queryFn: () => fetchTenants(1000, 0),
+ });
+
+ const availableParents =
+ parentQuery.data?.items?.filter((t) => t.id !== tenantId) || [];
+
const [name, setName] = useState("");
const [type, setType] = useState("COMPANY");
const [slug, setSlug] = useState("");
const [description, setDescription] = useState("");
const [status, setStatus] = useState("active");
const [domains, setDomains] = useState("");
+ const [parentId, setParentId] = useState("");
useEffect(() => {
if (tenantQuery.data) {
@@ -54,6 +64,7 @@ export function TenantProfilePage() {
setDescription(tenantQuery.data.description ?? "");
setStatus(tenantQuery.data.status);
setDomains(tenantQuery.data.domains?.join(", ") ?? "");
+ setParentId(tenantQuery.data.parentId ?? "");
}
}, [tenantQuery.data]);
@@ -65,6 +76,7 @@ export function TenantProfilePage() {
slug,
description: description || undefined,
status,
+ parentId: parentId || undefined,
domains: domains
.split(",")
.map((d) => d.trim())
@@ -197,6 +209,31 @@ export function TenantProfilePage() {
+
+
+
+
+ {t(
+ "ui.admin.tenants.profile.form.parent_help",
+ "가족사 테넌트나 하위 조직을 종속시킬 경우 상위 테넌트를 선택해주세요.",
+ )}
+
+