import { PluginCardVO } from '@/app/home/plugins/components/plugin-installed/PluginCardVO';
import { useState } from 'react';
import { Badge } from '@/components/ui/badge';
import { useTranslation } from 'react-i18next';
import {
BugIcon,
ExternalLink,
Ellipsis,
Trash,
ArrowUp,
Settings,
FileText,
} from 'lucide-react';
import { getCloudServiceClientSync } from '@/app/infra/http';
import { httpClient } from '@/app/infra/http/HttpClient';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import PluginComponentList from '@/app/home/plugins/components/plugin-installed/PluginComponentList';
export default function PluginCardComponent({
cardVO,
onCardClick,
onDeleteClick,
onUpgradeClick,
onViewReadme,
}: {
cardVO: PluginCardVO;
onCardClick: () => void;
onDeleteClick: (cardVO: PluginCardVO) => void;
onUpgradeClick: (cardVO: PluginCardVO) => void;
onViewReadme: (cardVO: PluginCardVO) => void;
}) {
const { t } = useTranslation();
const [dropdownOpen, setDropdownOpen] = useState(false);
const [isHovered, setIsHovered] = useState(false);
return (
<>
setIsHovered(true)}
onMouseLeave={() => {
if (!dropdownOpen) {
setIsHovered(false);
}
}}
>
{/* Icon - fixed width */}

{/* Content area - flexible width with min-width to prevent overflow */}
{/* Top content area - allows overflow with max height */}
{cardVO.author} / {cardVO.name}
{cardVO.label}
v{cardVO.version}
{cardVO.debug && (
{t('plugins.debugging')}
)}
{!cardVO.debug && (
<>
{cardVO.install_source === 'github' && (
{t('plugins.fromGithub')}
)}
{cardVO.install_source === 'local' && (
{t('plugins.fromLocal')}
)}
{cardVO.install_source === 'marketplace' && (
{t('plugins.fromMarketplace')}
)}
>
)}
{cardVO.description}
{/* Components list - fixed at bottom */}
{
const componentKindCount: Record = {};
for (const component of cardVO.components) {
const kind = component.manifest.manifest.kind;
if (componentKindCount[kind]) {
componentKindCount[kind]++;
} else {
componentKindCount[kind] = 1;
}
}
return componentKindCount;
})()}
showComponentName={false}
showTitle={true}
useBadge={false}
t={t}
/>
{/* Menu button - fixed width and position */}
{
setDropdownOpen(open);
if (!open) {
setIsHovered(false);
}
}}
>
{cardVO.hasUpdate && (
)}
{/**upgrade */}
{cardVO.install_source === 'marketplace' && (
{
e.stopPropagation();
onUpgradeClick(cardVO);
setDropdownOpen(false);
}}
>
{t('plugins.update')}
{cardVO.hasUpdate && (
{t('plugins.new')}
)}
)}
{/**view source */}
{(cardVO.install_source === 'github' ||
cardVO.install_source === 'marketplace') && (
{
e.stopPropagation();
if (cardVO.install_source === 'github') {
window.open(cardVO.install_info.github_url, '_blank');
} else if (cardVO.install_source === 'marketplace') {
window.open(
getCloudServiceClientSync().getPluginMarketplaceURL(
cardVO.author,
cardVO.name,
),
'_blank',
);
}
setDropdownOpen(false);
}}
>
{t('plugins.viewSource')}
)}
{
e.stopPropagation();
onDeleteClick(cardVO);
setDropdownOpen(false);
}}
>
{t('plugins.delete')}
{/* Hover overlay with action buttons */}
>
);
}