import { MoreVerticalIcon, PlusIcon } from "lucide-react"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import ConfirmDialog from "@/components/ConfirmDialog"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; import { identityProviderServiceClient } from "@/grpcweb"; import { IdentityProvider } from "@/types/proto/api/v1/idp_service"; import { useTranslate } from "@/utils/i18n"; import CreateIdentityProviderDialog from "../CreateIdentityProviderDialog"; import LearnMore from "../LearnMore"; import SettingSection from "./SettingSection"; import SettingTable from "./SettingTable"; const SSOSection = () => { const t = useTranslate(); const [identityProviderList, setIdentityProviderList] = useState([]); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); const [editingIdentityProvider, setEditingIdentityProvider] = useState(); const [deleteTarget, setDeleteTarget] = useState(undefined); useEffect(() => { fetchIdentityProviderList(); }, []); const fetchIdentityProviderList = async () => { const { identityProviders } = await identityProviderServiceClient.listIdentityProviders({}); setIdentityProviderList(identityProviders); }; const handleDeleteIdentityProvider = async (identityProvider: IdentityProvider) => { setDeleteTarget(identityProvider); }; const confirmDeleteIdentityProvider = async () => { if (!deleteTarget) return; try { await identityProviderServiceClient.deleteIdentityProvider({ name: deleteTarget.name }); } catch (error: any) { console.error(error); toast.error(error.details); } await fetchIdentityProviderList(); setDeleteTarget(undefined); }; const handleCreateIdentityProvider = () => { setEditingIdentityProvider(undefined); setIsCreateDialogOpen(true); }; const handleEditIdentityProvider = (identityProvider: IdentityProvider) => { setEditingIdentityProvider(identityProvider); setIsCreateDialogOpen(true); }; const handleDialogSuccess = async () => { await fetchIdentityProviderList(); setIsCreateDialogOpen(false); setEditingIdentityProvider(undefined); }; const handleDialogOpenChange = (open: boolean) => { setIsCreateDialogOpen(open); // Clear editing state when dialog is closed if (!open) { setEditingIdentityProvider(undefined); } }; return ( {t("setting.sso-section.sso-list")} } actions={ } > ( {provider.title} ({provider.type}) ), }, { key: "actions", header: "", className: "text-right", render: (_, provider: IdentityProvider) => ( handleEditIdentityProvider(provider)}>{t("common.edit")} handleDeleteIdentityProvider(provider)} className="text-destructive focus:text-destructive" > {t("common.delete")} ), }, ]} data={identityProviderList} emptyMessage={t("setting.sso-section.no-sso-found")} getRowKey={(provider) => provider.name} /> !open && setDeleteTarget(undefined)} title={deleteTarget ? t("setting.sso-section.confirm-delete", { name: deleteTarget.title }) : ""} confirmLabel={t("common.delete")} cancelLabel={t("common.cancel")} onConfirm={confirmDeleteIdentityProvider} confirmVariant="destructive" /> ); }; export default SSOSection;