feat: 添加制品中心页面及相关组件,支持创建和编辑制品功能;更新README文档

This commit is contained in:
xiongxiao
2026-03-23 18:45:34 +08:00
committed by cnb
parent 482206129f
commit b0acbbf337
13 changed files with 717 additions and 28 deletions

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { useCloudEnvStore } from './store'
import { useRepoStore } from '../repos/store'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
@@ -25,11 +26,14 @@ import {
Wind,
Plane,
Rocket,
ExternalLink
ExternalLink,
Info
} from 'lucide-react'
import { toast } from 'sonner'
import { WorkspaceInfo } from '@kevisual/cnb'
import clsx from 'clsx'
import { WorkspaceDetailDialog } from '../repos/modules/WorkspaceDetailDialog'
import { useShallow } from 'zustand/shallow'
type WorkspaceOpen = {
url?: string
@@ -61,13 +65,7 @@ const linkItems: LinkItem[] = [
{ key: 'jumpUrl', label: 'Jump', icon: <ExternalLink className="w-5 h-5" />, getUrl: (d) => d.jumpUrl },
{ key: 'webide', label: 'Web IDE', icon: <Code2 className="w-5 h-5" />, getUrl: (d) => d.webide },
{ key: 'vscode', label: 'VS Code', icon: <Code2 className="w-5 h-5" />, getUrl: (d) => d.vscode },
{ key: 'cursor', label: 'Cursor', icon: <MousePointer2 className="w-5 h-5" />, getUrl: (d) => d.cursor },
{ key: 'trae-cn', label: 'Trae', icon: <Rocket className="w-5 h-5" />, getUrl: (d) => d['trae-cn'] },
{ key: 'windsurf', label: 'Windsurf', icon: <Wind className="w-5 h-5" />, getUrl: (d) => d.windsurf },
{ key: 'antigravity', label: 'Antigravity', icon: <Plane className="w-5 h-5" />, getUrl: (d) => d.antigravity },
{ key: 'ssh', label: 'SSH', icon: <Lock className="w-5 h-5" />, getUrl: (d) => d.ssh },
{ key: 'remoteSsh', label: 'Remote SSH', icon: <Radio className="w-5 h-5" />, getUrl: (d) => d.remoteSsh },
{ key: 'codebuddycn', label: 'CodeBuddy', icon: <Zap className="w-5 h-5" />, getUrl: (d) => d.codebuddycn },
]
function LinkCard({ item, workspaceData }: { item: LinkItem; workspaceData: WorkspaceOpen }) {
@@ -127,6 +125,10 @@ function WorkspaceCard({ workspace, onStop }: { workspace: WorkspaceInfo; onStop
const [loading, setLoading] = useState(true)
const [workspaceData, setWorkspaceData] = useState<WorkspaceOpen | null>(null)
const getWorkspaceDetail = useCloudEnvStore((state) => state.getWorkspaceDetail)
const repoStore = useRepoStore(useShallow((state) => ({
setShowWorkspaceDialog: state.setShowWorkspaceDialog,
setWorkspaceTab: state.setWorkspaceTab,
})))
useEffect(() => {
const fetchDetail = async () => {
@@ -138,6 +140,16 @@ function WorkspaceCard({ workspace, onStop }: { workspace: WorkspaceInfo; onStop
fetchDetail()
}, [workspace, getWorkspaceDetail])
const handleShowDetail = async () => {
const data = await getWorkspaceDetail(workspace)
useRepoStore.setState({
selectWorkspace: workspace,
workspaceLink: data || {},
showWorkspaceDialog: true,
workspaceTab: 'dev'
})
}
return (
<Card className="p-4 space-y-4 border border-neutral-200 bg-white">
<div className="flex items-center justify-between">
@@ -153,15 +165,24 @@ function WorkspaceCard({ workspace, onStop }: { workspace: WorkspaceInfo; onStop
<Badge variant="outline" className="text-xs">{workspace.branch}</Badge>
)}
</div>
<Button
size="sm"
variant="outline"
onClick={() => onStop(workspace)}
className="text-red-600 border-red-200 hover:bg-red-600 hover:text-white"
>
<Square className="w-4 h-4 mr-1" />
</Button>
<div className="flex items-center gap-2">
<Button
size="sm"
variant="outline"
onClick={handleShowDetail}
>
<Info className="w-4 h-4" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() => onStop(workspace)}
className="text-red-600 border-red-200 hover:bg-red-600 hover:text-white"
>
<Square className="w-4 h-4 mr-1" />
</Button>
</div>
</div>
{loading ? (
@@ -171,7 +192,7 @@ function WorkspaceCard({ workspace, onStop }: { workspace: WorkspaceInfo; onStop
))}
</div>
) : workspaceData ? (
<div className="grid grid-cols-4 gap-2">
<div className="grid grid-cols-2 gap-2">
{linkItems.map((item) => (
<LinkCard key={item.key} item={item} workspaceData={workspaceData} />
))}
@@ -234,6 +255,7 @@ export default function CloudEnvPage() {
</div>
)}
</div>
<WorkspaceDetailDialog />
</SidebarLayout>
)
}
}