feat(web): base_branch selector with remote branch list in worktree creation

This commit is contained in:
2026-06-10 18:09:41 +08:00
parent 12ba5d5365
commit 112b99035c
2 changed files with 41 additions and 4 deletions
+5
View File
@@ -52,6 +52,11 @@ export const workspacesApi = {
release: (wtID: string) => release: (wtID: string) =>
request<Worktree>(`/api/v1/worktrees/${enc(wtID)}/release`, { method: 'POST' }), request<Worktree>(`/api/v1/worktrees/${enc(wtID)}/release`, { method: 'POST' }),
listBranches(wsID: string): Promise<string[]> {
return request<{ branches: string[] }>(`/api/v1/workspaces/${enc(wsID)}/branches`)
.then(r => r.branches)
},
// ===== Git ops ===== // ===== Git ops =====
statusOnMain: (wsID: string) => statusOnMain: (wsID: string) =>
request<FileStatus[]>(`/api/v1/workspaces/${enc(wsID)}/main/status`), request<FileStatus[]>(`/api/v1/workspaces/${enc(wsID)}/main/status`),
@@ -6,7 +6,7 @@
> >
<NButton <NButton
type="primary" type="primary"
@click="showCreate = true" @click="openCreate"
> >
新建 worktree 新建 worktree
</NButton> </NButton>
@@ -31,7 +31,13 @@
<NInput v-model:value="newBranch" /> <NInput v-model:value="newBranch" />
</NFormItem> </NFormItem>
<NFormItem label="基线分支(默认 default_branch)"> <NFormItem label="基线分支(默认 default_branch)">
<NInput v-model:value="newBase" /> <NSelect
v-model:value="newBase"
:options="baseBranchOptions"
:loading="branchesLoading"
clearable
placeholder="默认使用 default_branch"
/>
</NFormItem> </NFormItem>
</NForm> </NForm>
<template #footer> <template #footer>
@@ -71,11 +77,13 @@ import {
NForm, NForm,
NFormItem, NFormItem,
NInput, NInput,
NSelect,
useMessage, useMessage,
useDialog, useDialog,
} from 'naive-ui' } from 'naive-ui'
import type { DataTableColumns } from 'naive-ui' import type { DataTableColumns } from 'naive-ui'
import { useWorkspacesStore } from '@/stores/workspaces' import { useWorkspacesStore } from '@/stores/workspaces'
import { workspacesApi } from '@/api/workspaces'
import CommitDialog from './CommitDialog.vue' import CommitDialog from './CommitDialog.vue'
import type { Workspace, Worktree, WorktreeStatus } from '@/api/types' import type { Workspace, Worktree, WorktreeStatus } from '@/api/types'
@@ -87,16 +95,40 @@ const dialog = useDialog()
const showCreate = ref<boolean>(false) const showCreate = ref<boolean>(false)
const creating = ref<boolean>(false) const creating = ref<boolean>(false)
const newBranch = ref<string>('') const newBranch = ref<string>('')
const newBase = ref<string>('') const newBase = ref<string | null>(null)
const commitFor = ref<Worktree | null>(null) const commitFor = ref<Worktree | null>(null)
// Branch list for base_branch selector
const branches = ref<string[]>([])
const branchesLoading = ref(false)
const STATUS_TAG_TYPE: Record<WorktreeStatus, 'warning' | 'error' | 'default'> = { const STATUS_TAG_TYPE: Record<WorktreeStatus, 'warning' | 'error' | 'default'> = {
active: 'warning', active: 'warning',
pruning: 'error', pruning: 'error',
idle: 'default', idle: 'default',
} }
async function openCreate() {
showCreate.value = true
newBranch.value = ''
newBase.value = null
// Fetch branch list when dialog opens
branchesLoading.value = true
try {
branches.value = await workspacesApi.listBranches(props.ws.id)
} catch {
// Silently fail — user can still type manually
branches.value = []
} finally {
branchesLoading.value = false
}
}
const baseBranchOptions = computed(() =>
branches.value.map((b) => ({ label: b, value: b })),
)
async function onCreate() { async function onCreate() {
if (!newBranch.value.trim()) { if (!newBranch.value.trim()) {
msg.error('分支名为必填') msg.error('分支名为必填')
@@ -110,7 +142,7 @@ async function onCreate() {
}) })
showCreate.value = false showCreate.value = false
newBranch.value = '' newBranch.value = ''
newBase.value = '' newBase.value = null
} catch (e: unknown) { } catch (e: unknown) {
msg.error('创建失败:' + (e instanceof Error ? e.message : String(e))) msg.error('创建失败:' + (e instanceof Error ? e.message : String(e)))
} finally { } finally {