|
|
|
|
@@ -5,6 +5,9 @@
|
|
|
|
|
<span class="branch-icon">⎇</span>
|
|
|
|
|
<span class="branch-name">{{ branchName }}</span>
|
|
|
|
|
<span v-if="!showHistory" class="branch-count">{{ gitStatus?.changed_files.length ?? 0 }} {{ $t('gitChanges.changedFiles') }}</span>
|
|
|
|
|
<button v-if="!showHistory" class="branch-switch-btn" @click="onSwitchBranch" :title="$t('gitChanges.switchBranch')">
|
|
|
|
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-if="loading && !gitStatus" class="gc-skeleton">
|
|
|
|
|
@@ -54,6 +57,7 @@
|
|
|
|
|
<div v-if="selectedCommit" class="gc-commit-detail">
|
|
|
|
|
<div class="gc-commit-detail-header">
|
|
|
|
|
<span class="gc-commit-detail-hash">{{ selectedCommit.hash }}</span>
|
|
|
|
|
<span class="gc-commit-detail-author">{{ selectedCommit.author }}</span>
|
|
|
|
|
<span class="gc-commit-detail-msg">{{ selectedCommit.subject }}</span>
|
|
|
|
|
<span class="gc-commit-detail-time">{{ formatTime(selectedCommit.timestamp) }}</span>
|
|
|
|
|
<button class="gc-detail-close" @click="selectedCommit = null; commitDetail = null">✕</button>
|
|
|
|
|
@@ -96,6 +100,7 @@
|
|
|
|
|
@click="selectCommit(c)"
|
|
|
|
|
>
|
|
|
|
|
<span class="gc-commit-hash">{{ c.hash.slice(0, 8) }}</span>
|
|
|
|
|
<span class="gc-commit-author">{{ c.author }}</span>
|
|
|
|
|
<span class="gc-commit-msg">{{ c.subject }}</span>
|
|
|
|
|
<span class="gc-commit-time">{{ formatTime(c.timestamp) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
@@ -137,7 +142,7 @@ const diffContent = ref('')
|
|
|
|
|
const diffLoading = ref(false)
|
|
|
|
|
|
|
|
|
|
// 提交历史(分页)
|
|
|
|
|
const commits = ref<{ hash: string; subject: string; timestamp: number }[]>([])
|
|
|
|
|
const commits = ref<{ hash: string; subject: string; timestamp: number; author: string }[]>([])
|
|
|
|
|
const totalCommits = ref(0)
|
|
|
|
|
const hasMoreCommits = ref(false)
|
|
|
|
|
const loadingMore = ref(false)
|
|
|
|
|
@@ -145,7 +150,7 @@ const commitSkip = ref(0)
|
|
|
|
|
const COMMIT_PAGE_SIZE = 50
|
|
|
|
|
|
|
|
|
|
// 已选提交详情
|
|
|
|
|
const selectedCommit = ref<{ hash: string; subject: string; timestamp: number } | null>(null)
|
|
|
|
|
const selectedCommit = ref<{ hash: string; subject: string; timestamp: number; author: string } | null>(null)
|
|
|
|
|
const commitDetail = ref<{ files: { status: string; path: string }[]; diff: string } | null>(null)
|
|
|
|
|
const commitDetailLoading = ref(false)
|
|
|
|
|
const commitSelectedFile = ref('')
|
|
|
|
|
@@ -271,6 +276,11 @@ async function loadStatus() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 占位:分支切换后续接入(需拉取分支列表 + checkout IPC)。 */
|
|
|
|
|
function onSwitchBranch() {
|
|
|
|
|
// TODO: 弹出分支列表选择 + 调用 git checkout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function loadMoreCommits() {
|
|
|
|
|
if (loadingMore.value || !hasMoreCommits.value) return
|
|
|
|
|
loadingMore.value = true
|
|
|
|
|
@@ -311,7 +321,7 @@ async function selectFile(path: string) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 点击提交行 → 加载该提交的变更文件列表 */
|
|
|
|
|
async function selectCommit(c: { hash: string; subject: string; timestamp: number }) {
|
|
|
|
|
async function selectCommit(c: { hash: string; subject: string; timestamp: number; author: string }) {
|
|
|
|
|
selectedCommit.value = c
|
|
|
|
|
commitDetail.value = null
|
|
|
|
|
commitSelectedFile.value = ''
|
|
|
|
|
@@ -370,6 +380,21 @@ watch(() => props.moduleId, loadStatus, { immediate: true })
|
|
|
|
|
.branch-icon { font-size: 16px; }
|
|
|
|
|
.branch-name { font-weight: 600; color: var(--df-accent); }
|
|
|
|
|
.branch-count { margin-left: auto; font-size: 12px; color: var(--df-text-dim); }
|
|
|
|
|
.branch-switch-btn {
|
|
|
|
|
background: none;
|
|
|
|
|
border: none;
|
|
|
|
|
color: var(--df-text-dim);
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
padding: 2px 6px;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
transition: all 0.15s;
|
|
|
|
|
}
|
|
|
|
|
.branch-switch-btn:hover {
|
|
|
|
|
color: var(--df-text);
|
|
|
|
|
background: rgba(255,255,255,0.05);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Tabs */
|
|
|
|
|
.gc-tabs { display: flex; border-bottom: 0.5px solid var(--df-border); flex-shrink: 0; }
|
|
|
|
|
@@ -424,6 +449,12 @@ watch(() => props.moduleId, loadStatus, { immediate: true })
|
|
|
|
|
font-size: 11px; color: var(--df-accent); flex-shrink: 0;
|
|
|
|
|
}
|
|
|
|
|
.gc-commit-msg { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
|
|
|
|
|
.gc-commit-author {
|
|
|
|
|
font-size: 11px; color: var(--df-text-dim);
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
max-width: 100px;
|
|
|
|
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
.gc-commit-time { font-size: 11px; color: var(--df-text-dim); flex-shrink: 0; }
|
|
|
|
|
|
|
|
|
|
/* 提交详情 */
|
|
|
|
|
@@ -438,6 +469,10 @@ watch(() => props.moduleId, loadStatus, { immediate: true })
|
|
|
|
|
font-size: 11px; color: var(--df-accent);
|
|
|
|
|
}
|
|
|
|
|
.gc-commit-detail-msg { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
|
|
|
|
|
.gc-commit-detail-author {
|
|
|
|
|
font-size: 11px; color: var(--df-text-dim);
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
}
|
|
|
|
|
.gc-commit-detail-time { font-size: 11px; color: var(--df-text-dim); flex-shrink: 0; }
|
|
|
|
|
.gc-detail-close {
|
|
|
|
|
background: none; border: none; color: var(--df-text-dim);
|
|
|
|
|
|