forked from baron/baron-sso
기능 재배포
This commit is contained in:
@@ -53,6 +53,17 @@ import { t } from "../../../lib/i18n";
|
||||
|
||||
type DialogMode = "owner" | "admin";
|
||||
|
||||
function mergePendingMembers(
|
||||
members: TenantAdmin[],
|
||||
pendingMembers: TenantAdmin[],
|
||||
) {
|
||||
const existingIds = new Set(members.map((member) => member.id));
|
||||
return [
|
||||
...members,
|
||||
...pendingMembers.filter((member) => !existingIds.has(member.id)),
|
||||
];
|
||||
}
|
||||
|
||||
export function TenantAdminsAndOwnersTab() {
|
||||
const auth = useAuth();
|
||||
const currentUserId = auth.user?.profile.sub;
|
||||
@@ -60,6 +71,8 @@ export function TenantAdminsAndOwnersTab() {
|
||||
const queryClient = useQueryClient();
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [dialogMode, setDialogMode] = useState<DialogMode | null>(null);
|
||||
const [pendingOwners, setPendingOwners] = useState<TenantAdmin[]>([]);
|
||||
const [pendingAdmins, setPendingAdmins] = useState<TenantAdmin[]>([]);
|
||||
|
||||
if (!tenantId) return null;
|
||||
|
||||
@@ -95,18 +108,22 @@ export function TenantAdminsAndOwnersTab() {
|
||||
// Optimistically add to the list to prevent immediate double clicks
|
||||
const addedUser = searchResults.find((u) => u.id === userId);
|
||||
if (addedUser) {
|
||||
const optimisticOwner = {
|
||||
id: userId,
|
||||
name: addedUser.name,
|
||||
email: addedUser.email,
|
||||
};
|
||||
setPendingOwners((old) =>
|
||||
old.some((owner) => owner.id === userId)
|
||||
? old
|
||||
: [...old, optimisticOwner],
|
||||
);
|
||||
queryClient.setQueryData<TenantAdmin[]>(
|
||||
["tenant-owners", tenantId],
|
||||
(old) => {
|
||||
if (!old)
|
||||
return [
|
||||
{ id: userId, name: addedUser.name, email: addedUser.email },
|
||||
];
|
||||
if (!old) return [optimisticOwner];
|
||||
if (old.some((o) => o.id === userId)) return old;
|
||||
return [
|
||||
...old,
|
||||
{ id: userId, name: addedUser.name, email: addedUser.email },
|
||||
];
|
||||
return [...old, optimisticOwner];
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -125,6 +142,7 @@ export function TenantAdminsAndOwnersTab() {
|
||||
setSearchTerm("");
|
||||
},
|
||||
onError: (err: AxiosError<{ error?: string }>, userId, context) => {
|
||||
setPendingOwners((old) => old.filter((owner) => owner.id !== userId));
|
||||
if (context?.previousOwners) {
|
||||
queryClient.setQueryData(
|
||||
["tenant-owners", tenantId],
|
||||
@@ -148,6 +166,7 @@ export function TenantAdminsAndOwnersTab() {
|
||||
"tenant-owners",
|
||||
tenantId,
|
||||
]);
|
||||
setPendingOwners((old) => old.filter((owner) => owner.id !== userId));
|
||||
queryClient.setQueryData<TenantAdmin[]>(
|
||||
["tenant-owners", tenantId],
|
||||
(old) => (old ? old.filter((o) => o.id !== userId) : []),
|
||||
@@ -194,18 +213,22 @@ export function TenantAdminsAndOwnersTab() {
|
||||
|
||||
const addedUser = searchResults.find((u) => u.id === userId);
|
||||
if (addedUser) {
|
||||
const optimisticAdmin = {
|
||||
id: userId,
|
||||
name: addedUser.name,
|
||||
email: addedUser.email,
|
||||
};
|
||||
setPendingAdmins((old) =>
|
||||
old.some((admin) => admin.id === userId)
|
||||
? old
|
||||
: [...old, optimisticAdmin],
|
||||
);
|
||||
queryClient.setQueryData<TenantAdmin[]>(
|
||||
["tenant-admins", tenantId],
|
||||
(old) => {
|
||||
if (!old)
|
||||
return [
|
||||
{ id: userId, name: addedUser.name, email: addedUser.email },
|
||||
];
|
||||
if (!old) return [optimisticAdmin];
|
||||
if (old.some((a) => a.id === userId)) return old;
|
||||
return [
|
||||
...old,
|
||||
{ id: userId, name: addedUser.name, email: addedUser.email },
|
||||
];
|
||||
return [...old, optimisticAdmin];
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -223,6 +246,7 @@ export function TenantAdminsAndOwnersTab() {
|
||||
setSearchTerm("");
|
||||
},
|
||||
onError: (err: AxiosError<{ error?: string }>, userId, context) => {
|
||||
setPendingAdmins((old) => old.filter((admin) => admin.id !== userId));
|
||||
if (context?.previousAdmins) {
|
||||
queryClient.setQueryData(
|
||||
["tenant-admins", tenantId],
|
||||
@@ -246,6 +270,7 @@ export function TenantAdminsAndOwnersTab() {
|
||||
"tenant-admins",
|
||||
tenantId,
|
||||
]);
|
||||
setPendingAdmins((old) => old.filter((admin) => admin.id !== userId));
|
||||
queryClient.setQueryData<TenantAdmin[]>(
|
||||
["tenant-admins", tenantId],
|
||||
(old) => (old ? old.filter((a) => a.id !== userId) : []),
|
||||
@@ -312,8 +337,10 @@ export function TenantAdminsAndOwnersTab() {
|
||||
}
|
||||
};
|
||||
|
||||
const currentOwners = ownersQuery.data || [];
|
||||
const currentAdmins = adminsQuery.data || [];
|
||||
const serverOwners = ownersQuery.data || [];
|
||||
const serverAdmins = adminsQuery.data || [];
|
||||
const currentOwners = mergePendingMembers(serverOwners, pendingOwners);
|
||||
const currentAdmins = mergePendingMembers(serverAdmins, pendingAdmins);
|
||||
const searchResults = usersQuery.data?.items || [];
|
||||
const isDialogOpen = dialogMode !== null;
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
import * as React from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import {
|
||||
sortItems,
|
||||
toggleSort,
|
||||
type SortConfig,
|
||||
type SortResolverMap,
|
||||
sortItems,
|
||||
toggleSort,
|
||||
} from "../../../../../common/core/utils";
|
||||
import { RoleGuard } from "../../../components/auth/RoleGuard";
|
||||
import { Badge } from "../../../components/ui/badge";
|
||||
|
||||
Reference in New Issue
Block a user