generated from kevisual/vite-react-template
- 新增仓库列表页面,支持查看和管理 CNB 仓库 - 添加 AI 代理系统和状态管理 - 新增 tags-input、popover、textarea、tooltip 等 UI 组件 - 更新依赖:@kevisual/cnb 升级至 0.0.22,添加 idb-keyval - 改进路由守卫:未配置 API Key 时自动跳转配置页 - 优化 Dialog 遮罩层样式和整体布局 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Label } from '@/components/ui/label'
|
|
import { useRepoStore } from '../store'
|
|
import { useState, useEffect } from 'react'
|
|
import { get, set } from 'idb-keyval'
|
|
|
|
const SYNC_REPO_STORAGE_KEY = 'sync-repo-mapping'
|
|
|
|
export function SyncRepoDialog() {
|
|
const { syncDialogOpen, setSyncDialogOpen, selectedSyncRepo, buildSync } = useRepoStore()
|
|
const [toRepo, setToRepo] = useState('')
|
|
|
|
useEffect(() => {
|
|
const loadSavedMapping = async () => {
|
|
if (syncDialogOpen && selectedSyncRepo) {
|
|
const currentPath = selectedSyncRepo.path || ''
|
|
// 从 idb-keyval 获取存储的映射
|
|
const mapping = await get<Record<string, string>>(SYNC_REPO_STORAGE_KEY)
|
|
// 如果有存储的值,使用存储的值,否则使用当前仓库路径
|
|
setToRepo(mapping?.[currentPath] || currentPath)
|
|
}
|
|
}
|
|
loadSavedMapping()
|
|
}, [syncDialogOpen, selectedSyncRepo])
|
|
|
|
const handleSync = async () => {
|
|
if (!selectedSyncRepo || !toRepo.trim()) {
|
|
return
|
|
}
|
|
|
|
// 保存映射到 idb-keyval
|
|
const currentPath = selectedSyncRepo.path || ''
|
|
const mapping = await get<Record<string, string>>(SYNC_REPO_STORAGE_KEY) || {}
|
|
mapping[currentPath] = toRepo
|
|
await set(SYNC_REPO_STORAGE_KEY, mapping)
|
|
|
|
await buildSync(selectedSyncRepo, { toRepo })
|
|
setSyncDialogOpen(false)
|
|
}
|
|
|
|
return (
|
|
<Dialog open={syncDialogOpen} onOpenChange={setSyncDialogOpen}>
|
|
<DialogContent className="sm:max-w-[500px]">
|
|
<DialogHeader>
|
|
<DialogTitle>同步仓库到 Gitea</DialogTitle>
|
|
<DialogDescription>
|
|
将仓库 <span className="font-semibold text-neutral-900">{selectedSyncRepo?.path}</span> 同步到目标仓库
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4 py-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="toRepo">目标仓库路径</Label>
|
|
<Input
|
|
id="toRepo"
|
|
placeholder="例如: kevisual/my-repo"
|
|
value={toRepo}
|
|
onChange={(e) => setToRepo(e.target.value)}
|
|
/>
|
|
<p className="text-xs text-neutral-500">
|
|
格式: owner/repo-name
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-2">
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => setSyncDialogOpen(false)}
|
|
>
|
|
取消
|
|
</Button>
|
|
<Button
|
|
onClick={handleSync}
|
|
disabled={!toRepo.trim()}
|
|
>
|
|
开始同步
|
|
</Button>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|