generated from kevisual/vite-react-template
feat: add repository management dialogs and store functionality
- Implement CreateRepoDialog for creating new repositories with form validation. - Implement EditRepoDialog for editing existing repository details. - Implement SyncRepoDialog for syncing repositories with Gitea, including repository creation if necessary. - Implement WorkspaceDetailDialog for managing workspace links and actions. - Enhance the repo store with new state management for repository actions, including creating, editing, and syncing repositories. - Add build configuration utilities for repository synchronization. - Create a new page for repository management, integrating all dialogs and functionalities. - Add login route for authentication.
This commit is contained in:
140
src/pages/repo/modules/EditRepoDialog.tsx
Normal file
140
src/pages/repo/modules/EditRepoDialog.tsx
Normal file
@@ -0,0 +1,140 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { TagsInput } from '@/components/tags-input'
|
||||
import { useRepoStore } from '../store'
|
||||
|
||||
interface EditRepoDialogProps {
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
repo: {
|
||||
id: string
|
||||
path: string
|
||||
description: string
|
||||
site: string
|
||||
topics: string
|
||||
license: string
|
||||
} | null
|
||||
}
|
||||
|
||||
interface FormData {
|
||||
description: string
|
||||
site: string
|
||||
topics: string
|
||||
license: string
|
||||
}
|
||||
|
||||
export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps) {
|
||||
const { updateRepoInfo, getList } = useRepoStore()
|
||||
const { register, handleSubmit, reset, setValue } = useForm<FormData>()
|
||||
const [tags, setTags] = useState<string[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (repo) {
|
||||
const topicsArray = repo.topics ? repo.topics.split(',').map(t => t.trim()).filter(Boolean) : []
|
||||
setTags(topicsArray)
|
||||
reset({
|
||||
description: repo.description || '',
|
||||
site: repo.site || '',
|
||||
topics: repo.topics || '',
|
||||
license: repo.license || ''
|
||||
})
|
||||
}
|
||||
}, [repo, reset])
|
||||
|
||||
const onSubmit = async (data: FormData) => {
|
||||
if (!repo) return
|
||||
|
||||
await updateRepoInfo({
|
||||
path: repo.path,
|
||||
description: data.description?.trim() || '',
|
||||
site: data.site?.trim() || '',
|
||||
topics: tags.join(','),
|
||||
license: data.license?.trim() || '',
|
||||
})
|
||||
|
||||
await getList(true)
|
||||
onOpenChange(false)
|
||||
}
|
||||
|
||||
if (!repo) return null
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl!">
|
||||
<DialogHeader>
|
||||
<DialogTitle>编辑仓库信息</DialogTitle>
|
||||
<DialogDescription>{repo.path}</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="description">描述</Label>
|
||||
<Textarea
|
||||
id="description"
|
||||
{...register('description')}
|
||||
placeholder="输入仓库描述"
|
||||
className="w-full min-h-[100px]"
|
||||
rows={4}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="site">网站</Label>
|
||||
<Input
|
||||
id="site"
|
||||
{...register('site')}
|
||||
placeholder="https://example.com"
|
||||
type="url"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="topics">标签</Label>
|
||||
<TagsInput
|
||||
value={tags}
|
||||
onChange={setTags}
|
||||
placeholder="输入标签后按 Enter 或逗号添加"
|
||||
/>
|
||||
<p className="text-xs text-gray-500">按 Enter 或逗号添加标签,点击 × 删除</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="license">许可证</Label>
|
||||
<Input
|
||||
id="license"
|
||||
{...register('license')}
|
||||
placeholder="MIT, Apache-2.0, GPL-3.0 等"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => onOpenChange(false)}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button type="submit">
|
||||
保存
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user