mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-19 08:50:58 +00:00
feat: install market extensions from card click
This commit is contained in:
+21
-19
@@ -3,7 +3,7 @@ import { useRef, useState, useEffect } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import PluginComponentList from '../PluginComponentList';
|
import PluginComponentList from '../PluginComponentList';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Info, Package, Download, ExternalLink } from 'lucide-react';
|
import { Info, Package, ExternalLink } from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
@@ -85,9 +85,24 @@ export default function PluginMarketCardComponent({
|
|||||||
}, [cardVO.tags]);
|
}, [cardVO.tags]);
|
||||||
|
|
||||||
const remainingTags = cardVO.tags ? cardVO.tags.length - visibleTags : 0;
|
const remainingTags = cardVO.tags ? cardVO.tags.length - visibleTags : 0;
|
||||||
|
const handleInstallClick = () => {
|
||||||
|
onInstall?.(cardVO);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-[100%] h-[10rem] bg-white rounded-[10px] shadow-[0px_0px_4px_0_rgba(0,0,0,0.2)] p-3 sm:p-[1rem] hover:shadow-[0px_2px_8px_0_rgba(0,0,0,0.15)] transition-shadow duration-200 dark:bg-[#1f1f22] dark:shadow-[0px_0px_4px_0_rgba(255,255,255,0.1)] dark:hover:shadow-[0px_2px_8px_0_rgba(255,255,255,0.15)] relative">
|
<div
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
aria-label={t('market.installCard', { name: cardVO.label })}
|
||||||
|
className="w-[100%] h-[10rem] cursor-pointer bg-white rounded-[10px] shadow-[0px_0px_4px_0_rgba(0,0,0,0.2)] p-3 sm:p-[1rem] hover:shadow-[0px_2px_8px_0_rgba(0,0,0,0.15)] transition-shadow duration-200 outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 dark:bg-[#1f1f22] dark:shadow-[0px_0px_4px_0_rgba(255,255,255,0.1)] dark:hover:shadow-[0px_2px_8px_0_rgba(255,255,255,0.15)] relative"
|
||||||
|
onClick={handleInstallClick}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
|
event.preventDefault();
|
||||||
|
handleInstallClick();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div className="w-full h-full flex flex-col justify-between">
|
<div className="w-full h-full flex flex-col justify-between">
|
||||||
<div className="flex flex-row items-start justify-start gap-2 sm:gap-[1.2rem] min-h-0 flex-1 overflow-hidden">
|
<div className="flex flex-row items-start justify-start gap-2 sm:gap-[1.2rem] min-h-0 flex-1 overflow-hidden">
|
||||||
{iconFailed ? (
|
{iconFailed ? (
|
||||||
@@ -120,7 +135,10 @@ export default function PluginMarketCardComponent({
|
|||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger
|
<TooltipTrigger
|
||||||
asChild
|
asChild
|
||||||
onClick={(e) => e.preventDefault()}
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Badge
|
<Badge
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -159,22 +177,6 @@ export default function PluginMarketCardComponent({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row items-start justify-center gap-1 flex-shrink-0">
|
<div className="flex flex-row items-start justify-center gap-1 flex-shrink-0">
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
title={t('market.install')}
|
|
||||||
aria-label={t('market.install')}
|
|
||||||
className="h-7 w-7 rounded-md text-blue-600 hover:bg-blue-50 hover:text-blue-700 dark:text-blue-400 dark:hover:bg-blue-950/40 dark:hover:text-blue-300"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
if (onInstall) {
|
|
||||||
onInstall(cardVO);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Download className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -619,6 +619,7 @@ const enUS = {
|
|||||||
loading: 'Loading...',
|
loading: 'Loading...',
|
||||||
allLoaded: 'All plugins displayed',
|
allLoaded: 'All plugins displayed',
|
||||||
install: 'Install',
|
install: 'Install',
|
||||||
|
installCard: 'Install {{name}}',
|
||||||
installConfirm:
|
installConfirm:
|
||||||
'Are you sure you want to install plugin "{{name}}" ({{version}})?',
|
'Are you sure you want to install plugin "{{name}}" ({{version}})?',
|
||||||
downloadComplete: 'Plugin "{{name}}" download completed',
|
downloadComplete: 'Plugin "{{name}}" download completed',
|
||||||
|
|||||||
@@ -593,6 +593,7 @@ const zhHans = {
|
|||||||
loading: '加载中...',
|
loading: '加载中...',
|
||||||
allLoaded: '已显示全部插件',
|
allLoaded: '已显示全部插件',
|
||||||
install: '安装',
|
install: '安装',
|
||||||
|
installCard: '安装 {{name}}',
|
||||||
installConfirm: '确定要安装插件 "{{name}}" ({{version}}) 吗?',
|
installConfirm: '确定要安装插件 "{{name}}" ({{version}}) 吗?',
|
||||||
downloadComplete: '插件 "{{name}}" 下载完成',
|
downloadComplete: '插件 "{{name}}" 下载完成',
|
||||||
installFailed: '安装失败,请稍后重试',
|
installFailed: '安装失败,请稍后重试',
|
||||||
|
|||||||
@@ -586,6 +586,7 @@ const zhHant = {
|
|||||||
loading: '載入中...',
|
loading: '載入中...',
|
||||||
allLoaded: '已顯示全部插件',
|
allLoaded: '已顯示全部插件',
|
||||||
install: '安裝',
|
install: '安裝',
|
||||||
|
installCard: '安裝 {{name}}',
|
||||||
installConfirm: '確定要安裝插件 "{{name}}" ({{version}}) 嗎?',
|
installConfirm: '確定要安裝插件 "{{name}}" ({{version}}) 嗎?',
|
||||||
downloadComplete: '插件 "{{name}}" 下載完成',
|
downloadComplete: '插件 "{{name}}" 下載完成',
|
||||||
installFailed: '安裝失敗,請稍後重試',
|
installFailed: '安裝失敗,請稍後重試',
|
||||||
|
|||||||
Reference in New Issue
Block a user