generated from kevisual/vite-react-template
feat: 添加返回按钮和优化仓库卡片,移除未使用的 RepoInfoCard 组件
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user