import type { ReactNode } from 'react' import { useMutation } from '@tanstack/react-query' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { DropdownMenuGroup, DropdownMenuItem, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger } from '@/app/components/base/ui/dropdown-menu' import { Tooltip, TooltipContent, TooltipTrigger } from '@/app/components/base/ui/tooltip' import { Plan } from '@/app/components/billing/type' import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants' import { useModalContext } from '@/context/modal-context' import { useProviderContext } from '@/context/provider-context' import { getDocDownloadUrl } from '@/service/common' import { cn } from '@/utils/classnames' import { downloadUrl } from '@/utils/download' import Gdpr from '../../base/icons/src/public/common/Gdpr' import Iso from '../../base/icons/src/public/common/Iso' import Soc2 from '../../base/icons/src/public/common/Soc2' import SparklesSoft from '../../base/icons/src/public/common/SparklesSoft' import PremiumBadge from '../../base/premium-badge' import Spinner from '../../base/spinner' import Toast from '../../base/toast' import { MenuItemContent } from './menu-item-content' enum DocName { SOC2_Type_I = 'SOC2_Type_I', SOC2_Type_II = 'SOC2_Type_II', ISO_27001 = 'ISO_27001', GDPR = 'GDPR', } type ComplianceDocActionVisualProps = { isCurrentPlanCanDownload: boolean isPending: boolean tooltipText: string downloadText: string upgradeText: string } function ComplianceDocActionVisual({ isCurrentPlanCanDownload, isPending, tooltipText, downloadText, upgradeText, }: ComplianceDocActionVisualProps) { if (isCurrentPlanCanDownload) { return (
{downloadText} {isPending && }
) } const canShowUpgradeTooltip = tooltipText.length > 0 return (
{upgradeText}
)} /> {canShowUpgradeTooltip && ( {tooltipText} )}
) } type ComplianceDocRowItemProps = { icon: ReactNode label: ReactNode docName: DocName } function ComplianceDocRowItem({ icon, label, docName, }: ComplianceDocRowItemProps) { const { t } = useTranslation() const { plan } = useProviderContext() const { setShowPricingModal, setShowAccountSettingModal } = useModalContext() const isFreePlan = plan.type === Plan.sandbox const { isPending, mutate: downloadCompliance } = useMutation({ mutationKey: ['downloadCompliance', docName], mutationFn: async () => { try { const ret = await getDocDownloadUrl(docName) downloadUrl({ url: ret.url }) Toast.notify({ type: 'success', message: t('operation.downloadSuccess', { ns: 'common' }), }) } catch (error) { console.error(error) Toast.notify({ type: 'error', message: t('operation.downloadFailed', { ns: 'common' }), }) } }, }) const whichPlanCanDownloadCompliance = { [DocName.SOC2_Type_I]: [Plan.professional, Plan.team], [DocName.SOC2_Type_II]: [Plan.team], [DocName.ISO_27001]: [Plan.team], [DocName.GDPR]: [Plan.team, Plan.professional, Plan.sandbox], } const isCurrentPlanCanDownload = whichPlanCanDownloadCompliance[docName].includes(plan.type) const handleSelect = useCallback(() => { if (isCurrentPlanCanDownload) { if (!isPending) downloadCompliance() return } if (isFreePlan) setShowPricingModal() else setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.BILLING }) }, [downloadCompliance, isCurrentPlanCanDownload, isFreePlan, isPending, setShowAccountSettingModal, setShowPricingModal]) const upgradeTooltip: Record = { [Plan.sandbox]: t('compliance.sandboxUpgradeTooltip', { ns: 'common' }), [Plan.professional]: t('compliance.professionalUpgradeTooltip', { ns: 'common' }), [Plan.team]: '', [Plan.enterprise]: '', } return ( {icon}
{label}
) } // Submenu-only: this component must be rendered within an existing DropdownMenu root. export default function Compliance() { const { t } = useTranslation() return ( } label={t('compliance.soc2Type1', { ns: 'common' })} docName={DocName.SOC2_Type_I} /> } label={t('compliance.soc2Type2', { ns: 'common' })} docName={DocName.SOC2_Type_II} /> } label={t('compliance.iso27001', { ns: 'common' })} docName={DocName.ISO_27001} /> } label={t('compliance.gdpr', { ns: 'common' })} docName={DocName.GDPR} /> ) }