feat: 添加返回按钮和优化仓库卡片,移除未使用的 RepoInfoCard 组件

This commit is contained in:
2026-02-26 01:39:52 +08:00
parent a54597c65e
commit 245bbb33b0
5 changed files with 74 additions and 305 deletions

View File

@@ -13,7 +13,7 @@ import {
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover'
import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info, Eye, Square, LinkIcon, ExternalLink } from 'lucide-react'
import { Star, GitFork, FileText, Edit, FolderGit2, MoreVertical, FileText as IssueIcon, Settings, Play, Trash2, RefreshCw, BookOpen, Copy, Clock, Info, Eye, Square, LinkIcon, ExternalLink, ArrowLeft } from 'lucide-react'
import { useRepoStore } from '../store'
import { useMemo, useState } from 'react'
import { useShallow } from 'zustand/shallow'
@@ -24,26 +24,27 @@ import { useNavigate } from '@tanstack/react-router'
interface RepoCardProps {
repo: any
onStartWorkspace: (repo: any) => void
onEdit: (repo: any) => void
onIssue: (repo: any) => void
onSettings: (repo: any) => void
onDelete: (repo: any) => void
onSync?: (repo: any) => void
showReturn?: boolean
}
export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings, onDelete, onSync }: RepoCardProps) {
export function RepoCard({ showReturn = false, repo }: RepoCardProps) {
const [deletePopoverOpen, setDeletePopoverOpen] = useState(false)
const { workspaceList, getWorkspaceDetail, getList, buildUpdate, stopWorkspace } = useRepoStore(useShallow((state) => ({
const store = useRepoStore(useShallow((state) => ({
workspaceList: state.workspaceList,
getWorkspaceDetail: state.getWorkspaceDetail,
getList: state.getList,
buildUpdate: state.buildUpdate,
stopWorkspace: state.stopWorkspace,
setSelectedSyncRepo: state.setSelectedSyncRepo,
setSyncDialogOpen: state.setSyncDialogOpen,
startWorkspace: state.startWorkspace,
setEditRepo: state.setEditRepo,
setShowEditDialog: state.setShowEditDialog,
deleteItem: state.deleteItem,
})));
const workspace = useMemo(() => {
return workspaceList.find(ws => ws.slug === repo.path)
}, [workspaceList, repo.path])
return store.workspaceList.find(ws => ws.slug === repo.path)
}, [store.workspaceList, repo.path])
const isWorkspaceActive = !!workspace
const owner = repo.path.split('/')[0]
const isMine = myOrgs.includes(owner)
@@ -53,7 +54,7 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
const res = await app.run({ path: 'cnb', key: 'build-knowledge-base', payload: { repo: repo.path } })
if (res.code === 200) {
toast.success("知识库创建中")
getList({}, true)
store.getList({}, true)
}
}
const onClone = async () => {
@@ -65,18 +66,38 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
})
}
const onUpdate = async () => {
await buildUpdate({ path: repo.path });
await store.buildUpdate({ path: repo.path });
}
const handleIssue = (repo: any) => {
window.open(`https://cnb.cool/${repo.path}/-/issues`)
}
const handleSettings = (repo: any) => {
window.open(`https://cnb.cool/${repo.path}/-/settings`)
}
return (
<>
<Card className="relative p-0 overflow-hidden border border-neutral-200 bg-white hover:shadow-xl hover:border-neutral-300 transition-all duration-300 group pb-14">
<div className="p-6 space-y-4">
<div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-2 flex-1 min-w-0">
{showReturn && (
<button
onClick={() => navigate({ to: '/' })}
className="cursor-pointer flex items-center justify-center w-8 h-8 rounded-md hover:bg-neutral-100 transition-colors"
>
<ArrowLeft className="w-4 h-4 text-neutral-600" />
</button>
)}
<div
className="text-lg font-bold text-neutral-900 hover:text-neutral-600 transition-colors line-clamp-1 group-hover:underline"
onClick={() => {
navigate({ to: `/repo?repo=${repo.path}` })
if (!showReturn) {
navigate({ to: `/repo?repo=${repo.path}` })
} else {
window.open(`https://cnb.cool/${repo.path}`, '_blank')
}
}}
>
{repo.path}
@@ -114,7 +135,7 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
size="sm"
variant="outline"
onClick={() => {
stopWorkspace(workspace)
store.stopWorkspace(workspace)
}}
className="h-8 w-8 p-0 border-neutral-200 hover:border-red-600 hover:bg-red-600 hover:text-white transition-all cursor-pointer"
>
@@ -137,9 +158,9 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
variant="outline"
onClick={() => {
if (!isWorkspaceActive) {
onStartWorkspace(repo)
store.startWorkspace(repo)
} else {
getWorkspaceDetail(workspace)
store.getWorkspaceDetail(workspace)
}
}}
@@ -167,7 +188,10 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
}
/>
<DropdownMenuContent align="end" className="w-40">
<DropdownMenuItem onClick={() => onEdit(repo)} className="cursor-pointer">
<DropdownMenuItem onClick={() => {
store.setEditRepo(repo)
store.setShowEditDialog(true)
}} className="cursor-pointer">
<Edit className="w-4 h-4 mr-2" />
</DropdownMenuItem>
@@ -202,11 +226,11 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
<ExternalLink className="w-4 h-4 mr-2" />
访
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onIssue(repo)} className="cursor-pointer">
<DropdownMenuItem onClick={() => handleIssue(repo)} className="cursor-pointer">
<IssueIcon className="w-4 h-4 mr-2" />
访
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onSettings(repo)} className="cursor-pointer">
<DropdownMenuItem onClick={() => handleSettings(repo)} className="cursor-pointer">
<Settings className="w-4 h-4 mr-2" />
访
</DropdownMenuItem>
@@ -247,7 +271,8 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
variant="outline"
className="bg-red-600 text-white border-red-600 hover:bg-red-700 hover:border-red-700"
onClick={() => {
onDelete(repo)
if (repo.path)
store.deleteItem(repo.path)
setDeletePopoverOpen(false)
}}
>
@@ -309,7 +334,7 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
</span>
{isWorkspaceActive && <span className="flex items-center gap-1.5 hover:text-neutral-900 transition-colors cursor-pointer"
onClick={() => {
getWorkspaceDetail(workspace)
store.getWorkspaceDetail(workspace)
}}>
<Play className="w-3.5 h-3.5" />
<span className="font-medium"></span>
@@ -317,7 +342,10 @@ export function RepoCard({ repo, onStartWorkspace, onEdit, onIssue, onSettings,
{isMine && (
<span
className="flex items-center gap-1.5 hover:text-neutral-900 transition-colors cursor-pointer"
onClick={() => onSync?.(repo)}
onClick={() => {
store.setSelectedSyncRepo(repo)
store.setSyncDialogOpen(true)
}}
>
<RefreshCw className="w-3.5 h-3.5" />
<span className="font-medium"></span>