Skip to content

Commit 2e4174a

Browse files
committed
feat: dnd resize the column width
1 parent aa3eea1 commit 2e4174a

File tree

1 file changed

+173
-43
lines changed

1 file changed

+173
-43
lines changed

src/views/history/components/CommitTable.vue

Lines changed: 173 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,75 @@ const currentPage = ref(1)
2525
const observer = ref<IntersectionObserver | null>(null)
2626
const loadingTriggerRef = ref<HTMLElement | null>(null)
2727
28+
// 列宽度状态
29+
const columnWidths = ref({
30+
hash: 80,
31+
message: 400, // 给定初始宽度,不再使用 flex: 1
32+
stats: 140,
33+
author: 120,
34+
date: 160,
35+
})
36+
37+
// 拖拽状态
38+
const isDragging = ref(false)
39+
const currentColumn = ref('')
40+
const startX = ref(0)
41+
const startWidth = ref(0)
42+
43+
function handleDragStart(e: MouseEvent, column: string) {
44+
e.preventDefault()
45+
e.stopPropagation()
46+
47+
isDragging.value = true
48+
currentColumn.value = column
49+
startX.value = e.clientX
50+
startWidth.value = columnWidths.value[column]
51+
52+
document.addEventListener('mousemove', handleDragging, { passive: false })
53+
document.addEventListener('mouseup', handleDragEnd, { once: true })
54+
document.addEventListener('mouseleave', handleDragEnd, { once: true })
55+
document.addEventListener('keydown', handleKeyDown)
56+
57+
document.body.style.userSelect = 'none'
58+
document.body.style.cursor = 'col-resize'
59+
}
60+
61+
function handleDragging(e: MouseEvent) {
62+
if (!isDragging.value) {
63+
handleDragEnd()
64+
return
65+
}
66+
67+
e.preventDefault()
68+
e.stopPropagation()
69+
70+
const diff = e.clientX - startX.value
71+
const newWidth = Math.max(100, startWidth.value + diff)
72+
columnWidths.value[currentColumn.value] = newWidth
73+
}
74+
75+
function handleKeyDown(e: KeyboardEvent) {
76+
if (e.key === 'Escape') {
77+
handleDragEnd()
78+
}
79+
}
80+
81+
function handleDragEnd() {
82+
if (!isDragging.value)
83+
return
84+
85+
isDragging.value = false
86+
currentColumn.value = ''
87+
88+
document.removeEventListener('mousemove', handleDragging)
89+
document.removeEventListener('mouseup', handleDragEnd)
90+
document.removeEventListener('mouseleave', handleDragEnd)
91+
document.removeEventListener('keydown', handleKeyDown)
92+
93+
document.body.style.userSelect = ''
94+
document.body.style.cursor = ''
95+
}
96+
2897
function handleCommitClick(commit: Commit & { date: string }) {
2998
try {
3099
if (window.vscode) {
@@ -93,18 +162,51 @@ onUnmounted(() => {
93162
if (observer.value) {
94163
observer.value.disconnect()
95164
}
165+
if (isDragging.value) {
166+
handleDragEnd()
167+
}
96168
})
97169
</script>
98170

99171
<template>
100172
<div class="git-graph">
101-
<ul class="commit-list">
173+
<ul class="commit-list" :class="{ dragging: isDragging }">
102174
<li class="commit-header">
103-
<span class="hash-col">CommitId</span>
104-
<span class="message-col">Message</span>
105-
<span class="stats-col">Changes</span>
106-
<span class="author">Author</span>
107-
<span class="date">Date</span>
175+
<span class="hash-col column-header" :style="{ width: `${columnWidths.hash}px` }">
176+
CommitId
177+
<div
178+
class="resize-handle"
179+
:class="{ active: currentColumn === 'hash' }"
180+
@mousedown="handleDragStart($event, 'hash')"
181+
/>
182+
</span>
183+
<span class="message-col column-header" :style="{ width: `${columnWidths.message}px` }">
184+
Message
185+
<div
186+
class="resize-handle"
187+
:class="{ active: currentColumn === 'message' }"
188+
@mousedown="handleDragStart($event, 'message')"
189+
/>
190+
</span>
191+
<span class="stats-col column-header" :style="{ width: `${columnWidths.stats}px` }">
192+
Changes
193+
<div
194+
class="resize-handle"
195+
:class="{ active: currentColumn === 'stats' }"
196+
@mousedown="handleDragStart($event, 'stats')"
197+
/>
198+
</span>
199+
<span class="author column-header" :style="{ width: `${columnWidths.author}px` }">
200+
Author
201+
<div
202+
class="resize-handle"
203+
:class="{ active: currentColumn === 'author' }"
204+
@mousedown="handleDragStart($event, 'author')"
205+
/>
206+
</span>
207+
<span class="date column-header">
208+
Date
209+
</span>
108210
</li>
109211
<li
110212
v-for="commit in visibleCommits"
@@ -113,17 +215,17 @@ onUnmounted(() => {
113215
@click="handleCommitClick(commit)"
114216
@dblclick="handleDoubleClick"
115217
>
116-
<span class="hash-col">{{ commit.hash.substring(0, 7) }}</span>
117-
<span class="message-col">{{ commit.message }}</span>
118-
<span class="stats-col">
218+
<span class="hash-col" :style="{ width: `${columnWidths.hash}px` }">{{ commit.hash.substring(0, 7) }}</span>
219+
<span class="message-col" :style="{ width: `${columnWidths.message}px` }">{{ commit.message }}</span>
220+
<span class="stats-col" :style="{ width: `${columnWidths.stats}px` }">
119221
<span v-if="commit.stats" class="commit-stats">
120222
<span class="files">{{ commit.stats.files }} files</span>
121223
<span v-if="commit.stats.additions" class="additions">+{{ commit.stats.additions }}</span>
122224
<span v-if="commit.stats.deletions" class="deletions">-{{ commit.stats.deletions }}</span>
123225
</span>
124226
</span>
125-
<span class="author">{{ commit.authorName }}</span>
126-
<span class="date">{{ commit.date }}</span>
227+
<span class="author" :style="{ width: `${columnWidths.author}px` }">{{ commit.authorName }}</span>
228+
<span class="date" :style="{ width: `${columnWidths.date}px` }">{{ commit.date }}</span>
127229
</li>
128230
<li ref="loadingTriggerRef" class="loading-trigger">
129231
<div v-if="visibleCommits.length < graphData.length" class="loading-text">
@@ -148,80 +250,113 @@ onUnmounted(() => {
148250
list-style: none;
149251
font-size: var(--vscode-font-size);
150252
color: var(--vscode-foreground);
253+
min-width: min-content;
151254
}
152255
153256
.commit-header {
154257
position: sticky;
155258
top: 0;
156259
display: flex;
157260
align-items: center;
158-
padding: 8px;
159261
background-color: var(--vscode-sideBar-background);
160262
border-bottom: 1px solid var(--vscode-panel-border);
161263
font-weight: bold;
264+
width: 100%;
265+
box-sizing: border-box;
266+
padding: 8px;
267+
z-index: 2;
162268
}
163269
164270
.commit-row {
165271
display: flex;
166272
align-items: center;
167-
padding: 8px;
168273
border-bottom: 1px solid var(--vscode-panel-border);
169274
cursor: pointer;
170-
gap: 5px;
275+
width: 100%;
276+
box-sizing: border-box;
277+
padding: 8px;
171278
}
172279
173280
.commit-row:hover {
174281
background-color: var(--vscode-list-hoverBackground);
175282
}
176283
177-
.hash-col {
178-
width: 80px;
179-
padding-right: 8px;
284+
.column-header,
285+
.hash-col,
286+
.message-col,
287+
.stats-col,
288+
.author,
289+
.date {
290+
position: relative;
291+
box-sizing: border-box;
292+
padding: 0 8px;
180293
white-space: nowrap;
181294
overflow: hidden;
182295
text-overflow: ellipsis;
296+
display: flex;
297+
align-items: center;
183298
}
184299
185-
.commit-row .hash-col {
186-
color: var(--vscode-gitDecoration-addedResourceForeground);
300+
.column-header {
301+
user-select: none;
187302
}
188303
189-
.commit-row .hash-col:hover {
190-
text-decoration: underline;
304+
.hash-col {
305+
width: 80px;
306+
color: var(--vscode-gitDecoration-addedResourceForeground);
191307
}
192308
193309
.message-col {
194-
flex: 1;
195-
padding-right: 8px;
196-
white-space: nowrap;
197-
overflow: hidden;
198-
text-overflow: ellipsis;
310+
min-width: 100px;
199311
}
200312
201313
.stats-col {
202314
width: 140px;
203-
padding-right: 8px;
204-
white-space: nowrap;
205-
overflow: hidden;
206-
text-overflow: ellipsis;
207315
}
208316
209317
.author {
210318
width: 120px;
211-
padding-right: 8px;
212-
white-space: nowrap;
213-
overflow: hidden;
214-
text-overflow: ellipsis;
215319
}
216320
217321
.date {
218322
width: 160px;
219-
white-space: nowrap;
220-
overflow: hidden;
221-
text-overflow: ellipsis;
323+
padding-right: 16px;
222324
color: var(--vscode-descriptionForeground);
223325
}
224326
327+
.resize-handle {
328+
position: absolute;
329+
right: 0;
330+
top: 0;
331+
bottom: 0;
332+
width: 3px;
333+
cursor: col-resize;
334+
background: var(--vscode-scrollbarSlider-hoverBackground);
335+
opacity: 0.6;
336+
z-index: 1;
337+
transition: background-color 0.1s ease;
338+
}
339+
340+
.resize-handle:hover {
341+
background: var(--vscode-activityBar-activeBorder);
342+
opacity: 0.8;
343+
}
344+
345+
.resize-handle.active {
346+
background: var(--vscode-activityBar-activeBorder);
347+
opacity: 1;
348+
}
349+
350+
.commit-list.dragging {
351+
cursor: col-resize;
352+
}
353+
354+
.commit-list.dragging .resize-handle.active {
355+
display: block;
356+
background: var(--vscode-activityBar-activeBorder);
357+
opacity: 1;
358+
}
359+
225360
.commit-stats {
226361
display: inline-flex;
227362
gap: 8px;
@@ -238,17 +373,12 @@ onUnmounted(() => {
238373
}
239374
240375
.loading-trigger {
241-
text-align: center;
242376
padding: 8px;
377+
text-align: center;
243378
}
244379
245380
.loading-text {
246381
font-size: 12px;
247382
color: var(--vscode-descriptionForeground);
248383
}
249-
250-
/* Ensure the graph lines remain visible when hovering */
251-
.commit-row:hover .commit-line {
252-
opacity: 0.8;
253-
}
254384
</style>

0 commit comments

Comments
 (0)