Download src/components/features/plugins/plugin-card.tsx from SaylorTwift/openhands: direct link, hf CLI and curl.
- Browser
- Download file 4.01 kB
-
https://huggingface.co/SaylorTwift/openhands/resolve/main/src/components/features/plugins/plugin-card.tsx
- Command line
-
hf download hf://SaylorTwift/openhands/src/components/features/plugins/plugin-card.tsx
-
curl -L -o plugin-card.tsx https://huggingface.co/SaylorTwift/openhands/resolve/main/src/components/features/plugins/plugin-card.tsx
4.01 kB
| import React from "react"; | |
| import { useTranslation } from "react-i18next"; | |
| import { I18nKey } from "#/i18n/declaration"; | |
| import { cn } from "#/utils/utils"; | |
| import { CirclePlusCheckToggle } from "#/components/shared/buttons/circle-plus-check-toggle"; | |
| import { BrandButton } from "#/components/features/settings/brand-button"; | |
| import { | |
| extensionModuleCardInteractiveClassName, | |
| extensionModuleCardPillClassName, | |
| extensionModuleCardSurfaceClassName, | |
| } from "#/utils/extension-module-card-classes"; | |
| import type { PluginViewModel } from "./build-plugins-view-model"; | |
| interface PluginCardProps { | |
| plugin: PluginViewModel; | |
| /** A mutation targeting this plugin is in flight. */ | |
| isBusy?: boolean; | |
| /** Management actions are unavailable (e.g. non-local backend). */ | |
| isDisabled?: boolean; | |
| onOpen: () => void; | |
| onInstall: () => void; | |
| onToggle: (enabled: boolean) => void; | |
| } | |
| export function PluginCard({ | |
| plugin, | |
| isBusy = false, | |
| isDisabled = false, | |
| onOpen, | |
| onInstall, | |
| onToggle, | |
| }: PluginCardProps) { | |
| const { t } = useTranslation("openhands"); | |
| const handleKeyDown = (event: React.KeyboardEvent) => { | |
| if (event.key === "Enter" || event.key === " ") { | |
| event.preventDefault(); | |
| onOpen(); | |
| } | |
| }; | |
| const handleInstall = (event?: React.MouseEvent<HTMLButtonElement>) => { | |
| event?.stopPropagation(); | |
| onInstall(); | |
| }; | |
| return ( | |
| <div | |
| data-testid={`plugin-card-${plugin.name}`} | |
| role="button" | |
| tabIndex={0} | |
| onClick={onOpen} | |
| onKeyDown={handleKeyDown} | |
| className={cn( | |
| "flex min-w-0 flex-col gap-3 overflow-hidden p-4", | |
| extensionModuleCardSurfaceClassName, | |
| extensionModuleCardInteractiveClassName, | |
| )} | |
| > | |
| <header className="flex items-start justify-between gap-3"> | |
| <div className="min-w-0 flex-1"> | |
| <h3 | |
| data-testid={`plugin-name-${plugin.name}`} | |
| className="truncate text-sm font-semibold text-white" | |
| > | |
| {plugin.name} | |
| </h3> | |
| {plugin.source ? ( | |
| <p | |
| data-testid={`plugin-source-${plugin.name}`} | |
| className="mt-0.5 min-w-0 truncate text-xs text-tertiary-alt" | |
| title={plugin.source} | |
| > | |
| {plugin.source} | |
| </p> | |
| ) : null} | |
| </div> | |
| {plugin.installed ? ( | |
| <CirclePlusCheckToggle | |
| testId={`plugin-toggle-${plugin.name}`} | |
| isSelected={plugin.enabled} | |
| isDisabled={isDisabled || isBusy} | |
| onToggle={onToggle} | |
| disableTooltipKey={I18nKey.COMMON$DISABLE} | |
| /> | |
| ) : plugin.isLocal ? ( | |
| <span | |
| data-testid={`plugin-local-badge-${plugin.name}`} | |
| className={cn(extensionModuleCardPillClassName, "flex-shrink-0")} | |
| > | |
| {t(I18nKey.SETTINGS$PLUGINS_FILTER_LOCAL)} | |
| </span> | |
| ) : ( | |
| <BrandButton | |
| type="button" | |
| variant="secondary" | |
| testId={`plugin-install-${plugin.name}`} | |
| isDisabled={isDisabled || isBusy} | |
| className="flex-shrink-0 whitespace-nowrap" | |
| onClick={handleInstall} | |
| > | |
| {t( | |
| isBusy | |
| ? I18nKey.SETTINGS$PLUGINS_INSTALLING | |
| : I18nKey.SETTINGS$PLUGINS_INSTALL, | |
| )} | |
| </BrandButton> | |
| )} | |
| </header> | |
| {plugin.description ? ( | |
| <p | |
| data-testid={`plugin-description-${plugin.name}`} | |
| className="line-clamp-2 break-words text-xs leading-relaxed text-tertiary-light" | |
| > | |
| {plugin.description} | |
| </p> | |
| ) : null} | |
| {(plugin.installed || plugin.isLocal) && plugin.version ? ( | |
| <span | |
| data-testid={`plugin-version-${plugin.name}`} | |
| className={cn(extensionModuleCardPillClassName, "self-start")} | |
| > | |
| {t(I18nKey.SETTINGS$SKILLS_VERSION, { version: plugin.version })} | |
| </span> | |
| ) : null} | |
| </div> | |
| ); | |
| } | |