@civilization/dsh-git-workbench 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +55 -107
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client/GitBranchPill.module.css +105 -87
- package/src/client/GitBranchPill.tsx +15 -42
- package/src/client/locales.ts +31 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@civilization/dsh-git-workbench",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "IntelliJ IDEA-grade Git Workbench, DAG topology graph, branch switcher, tag manager and agent tools for DeepSeek Harness.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Status bar Git branch pill and popover branch switcher (
|
|
1
|
+
/* Status bar Git branch pill and popover branch switcher (Clean & Elegant UI) */
|
|
2
2
|
|
|
3
3
|
.anchor {
|
|
4
4
|
position: relative;
|
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
gap: 6px;
|
|
15
15
|
box-sizing: border-box;
|
|
16
16
|
max-width: 100%;
|
|
17
|
-
padding:
|
|
18
|
-
border: 0.5px solid var(--dsw-alias-border-l2);
|
|
19
|
-
border-radius: var(--dsw-radius-sm);
|
|
20
|
-
background: var(--dsw-alias-bg-
|
|
21
|
-
color: var(--dsw-alias-label-
|
|
17
|
+
padding: 2px 8px;
|
|
18
|
+
border: 0.5px solid var(--dsw-alias-border-l2, #cbd5e1);
|
|
19
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
20
|
+
background: var(--dsw-alias-interactive-bg-hover, #f1f5f9);
|
|
21
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
22
22
|
font: inherit;
|
|
23
|
-
font-weight:
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
font-size: 12px;
|
|
24
25
|
font-variant-numeric: tabular-nums;
|
|
25
26
|
line-height: inherit;
|
|
26
27
|
white-space: nowrap;
|
|
@@ -30,21 +31,16 @@
|
|
|
30
31
|
|
|
31
32
|
.pill:hover,
|
|
32
33
|
.pill[aria-expanded='true'] {
|
|
33
|
-
background: var(--dsw-alias-interactive-bg-
|
|
34
|
-
border-color: var(--dsw-alias-border-l1);
|
|
35
|
-
color: var(--dsw-alias-label-primary);
|
|
34
|
+
background: var(--dsw-alias-interactive-bg-active, #e2e8f0);
|
|
35
|
+
border-color: var(--dsw-alias-border-l1, #94a3b8);
|
|
36
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
.icon {
|
|
39
40
|
width: 14px;
|
|
40
41
|
height: 14px;
|
|
41
42
|
flex: none;
|
|
42
|
-
color: var(--dsw-alias-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.pill:hover .icon,
|
|
46
|
-
.pill[aria-expanded='true'] .icon {
|
|
47
|
-
color: var(--dsw-alias-state-business-primary);
|
|
43
|
+
color: var(--dsw-alias-state-business-primary, #2563eb);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
.branchName {
|
|
@@ -62,35 +58,36 @@
|
|
|
62
58
|
font-size: 11px;
|
|
63
59
|
line-height: 14px;
|
|
64
60
|
font-weight: 500;
|
|
65
|
-
background:
|
|
66
|
-
color: var(--dsw-alias-label-secondary);
|
|
61
|
+
background: rgba(0, 0, 0, 0.06);
|
|
62
|
+
color: var(--dsw-alias-label-secondary, #475569);
|
|
67
63
|
}
|
|
68
64
|
|
|
69
65
|
.badgeAhead {
|
|
70
|
-
color: var(--dsw-alias-state-business-primary);
|
|
66
|
+
color: var(--dsw-alias-state-business-primary, #2563eb);
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
.badgeBehind {
|
|
74
|
-
color: var(--dsw-alias-state-warn-primary);
|
|
70
|
+
color: var(--dsw-alias-state-warn-primary, #d97706);
|
|
75
71
|
}
|
|
76
72
|
|
|
77
73
|
/* Branch switch popover panel (wrapped in MenuSurface) */
|
|
78
74
|
.popover {
|
|
79
75
|
position: fixed;
|
|
80
76
|
z-index: 1100;
|
|
81
|
-
width:
|
|
82
|
-
max-height:
|
|
77
|
+
width: 320px;
|
|
78
|
+
max-height: 480px;
|
|
83
79
|
display: flex;
|
|
84
80
|
flex-direction: column;
|
|
85
81
|
box-sizing: border-box;
|
|
86
82
|
background: var(--dsw-alias-bg-overlay, var(--dsw-alias-bg-layer-1, #ffffff));
|
|
87
|
-
border:
|
|
88
|
-
border-radius: var(--dsw-radius-
|
|
89
|
-
--dsw-elevation-stroke-color: var(--dsw-alias-border-l1);
|
|
90
|
-
box-shadow:
|
|
91
|
-
color: var(--dsw-alias-label-primary);
|
|
92
|
-
font-size:
|
|
83
|
+
border: 1px solid var(--dsw-alias-border-l1, #e2e8f0);
|
|
84
|
+
border-radius: var(--dsw-radius-xl, 14px);
|
|
85
|
+
--dsw-elevation-stroke-color: var(--dsw-alias-border-l1, #e2e8f0);
|
|
86
|
+
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
87
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
88
|
+
font-size: 13px;
|
|
93
89
|
line-height: 18px;
|
|
90
|
+
padding: 10px;
|
|
94
91
|
overflow: hidden;
|
|
95
92
|
cursor: default;
|
|
96
93
|
animation: popoverFadeIn 0.15s cubic-bezier(0.16, 1, 0.3, 1);
|
|
@@ -99,7 +96,7 @@
|
|
|
99
96
|
@keyframes popoverFadeIn {
|
|
100
97
|
from {
|
|
101
98
|
opacity: 0;
|
|
102
|
-
transform: translateY(
|
|
99
|
+
transform: translateY(6px) scale(0.98);
|
|
103
100
|
}
|
|
104
101
|
to {
|
|
105
102
|
opacity: 1;
|
|
@@ -108,48 +105,42 @@
|
|
|
108
105
|
}
|
|
109
106
|
|
|
110
107
|
.header {
|
|
111
|
-
padding: 8px 10px 6px;
|
|
112
|
-
border-bottom: 0.5px solid var(--dsw-alias-border-l2);
|
|
113
108
|
display: flex;
|
|
114
109
|
flex-direction: column;
|
|
115
|
-
gap:
|
|
110
|
+
gap: 8px;
|
|
111
|
+
padding-bottom: 8px;
|
|
112
|
+
border-bottom: 0.5px solid var(--dsw-alias-border-l2, #e2e8f0);
|
|
116
113
|
}
|
|
117
114
|
|
|
118
115
|
.searchRow {
|
|
119
116
|
display: flex;
|
|
120
117
|
align-items: center;
|
|
121
118
|
gap: 6px;
|
|
122
|
-
padding:
|
|
123
|
-
border-radius: var(--dsw-radius-
|
|
124
|
-
background: var(--dsw-alias-
|
|
125
|
-
border:
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.searchIcon {
|
|
129
|
-
width: 13px;
|
|
130
|
-
height: 13px;
|
|
131
|
-
color: var(--dsw-alias-label-tertiary);
|
|
132
|
-
flex: none;
|
|
119
|
+
padding: 6px 10px;
|
|
120
|
+
border-radius: var(--dsw-radius-md, 8px);
|
|
121
|
+
background: var(--dsw-alias-bg-base, #f8fafc);
|
|
122
|
+
border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
|
|
133
123
|
}
|
|
134
124
|
|
|
135
125
|
.searchInput {
|
|
136
126
|
flex: 1;
|
|
137
127
|
border: none;
|
|
138
128
|
background: transparent;
|
|
139
|
-
color: var(--dsw-alias-label-primary);
|
|
140
|
-
font-size:
|
|
129
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
130
|
+
font-size: 13px;
|
|
131
|
+
line-height: 18px;
|
|
141
132
|
outline: none;
|
|
142
133
|
}
|
|
143
134
|
|
|
144
135
|
.searchInput::placeholder {
|
|
145
|
-
color: var(--dsw-alias-label-tertiary);
|
|
136
|
+
color: var(--dsw-alias-label-tertiary, #94a3b8);
|
|
146
137
|
}
|
|
147
138
|
|
|
148
139
|
.actionBar {
|
|
149
140
|
display: flex;
|
|
150
141
|
align-items: center;
|
|
151
142
|
justify-content: space-between;
|
|
152
|
-
gap:
|
|
143
|
+
gap: 6px;
|
|
153
144
|
}
|
|
154
145
|
|
|
155
146
|
.toolBtnGroup {
|
|
@@ -161,13 +152,14 @@
|
|
|
161
152
|
.toolBtn {
|
|
162
153
|
display: inline-flex;
|
|
163
154
|
align-items: center;
|
|
155
|
+
justify-content: center;
|
|
164
156
|
gap: 4px;
|
|
165
|
-
padding:
|
|
166
|
-
border:
|
|
167
|
-
border-radius: var(--dsw-radius-sm);
|
|
168
|
-
background: var(--dsw-alias-interactive-bg-hover);
|
|
169
|
-
color: var(--dsw-alias-label-secondary);
|
|
170
|
-
font-size:
|
|
157
|
+
padding: 4px 10px;
|
|
158
|
+
border: none;
|
|
159
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
160
|
+
background: var(--dsw-alias-interactive-bg-hover, #f1f5f9);
|
|
161
|
+
color: var(--dsw-alias-label-secondary, #475569);
|
|
162
|
+
font-size: 12px;
|
|
171
163
|
font-family: inherit;
|
|
172
164
|
font-weight: 500;
|
|
173
165
|
cursor: pointer;
|
|
@@ -175,8 +167,29 @@
|
|
|
175
167
|
}
|
|
176
168
|
|
|
177
169
|
.toolBtn:hover {
|
|
178
|
-
background: var(--dsw-alias-interactive-bg-active);
|
|
179
|
-
color: var(--dsw-alias-label-primary);
|
|
170
|
+
background: var(--dsw-alias-interactive-bg-active, #e2e8f0);
|
|
171
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.toolBtnPrimary {
|
|
175
|
+
display: inline-flex;
|
|
176
|
+
align-items: center;
|
|
177
|
+
gap: 4px;
|
|
178
|
+
padding: 4px 10px;
|
|
179
|
+
border: none;
|
|
180
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
181
|
+
background: var(--dsw-alias-interactive-bg-hover, #f1f5f9);
|
|
182
|
+
color: var(--dsw-alias-label-primary, #334155);
|
|
183
|
+
font-size: 12px;
|
|
184
|
+
font-family: inherit;
|
|
185
|
+
font-weight: 500;
|
|
186
|
+
cursor: pointer;
|
|
187
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.toolBtnPrimary:hover {
|
|
191
|
+
background: var(--dsw-alias-interactive-bg-active, #e2e8f0);
|
|
192
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
180
193
|
}
|
|
181
194
|
|
|
182
195
|
.btnIcon {
|
|
@@ -193,33 +206,36 @@
|
|
|
193
206
|
|
|
194
207
|
.newBranchInput {
|
|
195
208
|
flex: 1;
|
|
196
|
-
padding:
|
|
197
|
-
border-radius: var(--dsw-radius-sm);
|
|
198
|
-
border:
|
|
199
|
-
background: var(--dsw-alias-
|
|
200
|
-
color: var(--dsw-alias-label-primary);
|
|
209
|
+
padding: 5px 10px;
|
|
210
|
+
border-radius: var(--dsw-radius-sm, 6px);
|
|
211
|
+
border: 1px solid var(--dsw-alias-state-business-primary, #2563eb);
|
|
212
|
+
background: var(--dsw-alias-bg-base, #f8fafc);
|
|
213
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
201
214
|
font-size: 12px;
|
|
202
215
|
outline: none;
|
|
203
216
|
}
|
|
204
217
|
|
|
205
218
|
.newBranchInput::placeholder {
|
|
206
|
-
color: var(--dsw-alias-label-tertiary);
|
|
219
|
+
color: var(--dsw-alias-label-tertiary, #94a3b8);
|
|
207
220
|
}
|
|
208
221
|
|
|
209
222
|
.branchList {
|
|
210
223
|
flex: 1;
|
|
211
224
|
overflow-y: auto;
|
|
212
|
-
|
|
225
|
+
display: flex;
|
|
226
|
+
flex-direction: column;
|
|
227
|
+
gap: 2px;
|
|
228
|
+
padding: 4px 0 0 0;
|
|
213
229
|
}
|
|
214
230
|
|
|
215
231
|
.groupLabel {
|
|
216
232
|
display: flex;
|
|
217
233
|
align-items: center;
|
|
218
234
|
gap: 6px;
|
|
219
|
-
padding:
|
|
220
|
-
font-size:
|
|
221
|
-
font-weight:
|
|
222
|
-
color: var(--dsw-alias-label-tertiary);
|
|
235
|
+
padding: 8px 8px 4px 8px;
|
|
236
|
+
font-size: 12px;
|
|
237
|
+
font-weight: 400;
|
|
238
|
+
color: var(--dsw-alias-label-tertiary, #94a3b8);
|
|
223
239
|
}
|
|
224
240
|
|
|
225
241
|
.branchItem {
|
|
@@ -227,50 +243,52 @@
|
|
|
227
243
|
align-items: center;
|
|
228
244
|
justify-content: space-between;
|
|
229
245
|
width: 100%;
|
|
230
|
-
|
|
231
|
-
|
|
246
|
+
box-sizing: border-box;
|
|
247
|
+
padding: 7px 10px;
|
|
248
|
+
border-radius: var(--dsw-radius-sm, 8px);
|
|
232
249
|
border: none;
|
|
233
250
|
background: transparent;
|
|
234
|
-
color: var(--dsw-alias-label-secondary);
|
|
251
|
+
color: var(--dsw-alias-label-secondary, #334155);
|
|
235
252
|
font: inherit;
|
|
236
|
-
font-size:
|
|
253
|
+
font-size: 13px;
|
|
254
|
+
font-weight: 400;
|
|
237
255
|
text-align: left;
|
|
238
256
|
cursor: pointer;
|
|
239
257
|
transition: background 0.12s ease, color 0.12s ease;
|
|
240
258
|
}
|
|
241
259
|
|
|
242
|
-
.branchItem:hover {
|
|
243
|
-
background: var(--dsw-alias-
|
|
244
|
-
color: var(--dsw-alias-label-primary);
|
|
260
|
+
.branchItem:hover:not(.currentBranch) {
|
|
261
|
+
background: var(--dsw-alias-bg-base, #f8fafc);
|
|
262
|
+
color: var(--dsw-alias-label-primary, #0f172a);
|
|
245
263
|
}
|
|
246
264
|
|
|
247
265
|
.currentBranch {
|
|
248
|
-
background: var(--dsw-alias-
|
|
249
|
-
color: var(--dsw-alias-state-business-primary);
|
|
250
|
-
font-weight:
|
|
266
|
+
background: var(--dsw-alias-state-business-muted, #eff6ff) !important;
|
|
267
|
+
color: var(--dsw-alias-state-business-primary, #2563eb) !important;
|
|
268
|
+
font-weight: 600 !important;
|
|
251
269
|
}
|
|
252
270
|
|
|
253
271
|
.currentBranch:hover {
|
|
254
|
-
background: var(--dsw-alias-
|
|
272
|
+
background: var(--dsw-alias-state-business-muted, #eff6ff) !important;
|
|
255
273
|
}
|
|
256
274
|
|
|
257
275
|
.branchItemLeft {
|
|
258
276
|
display: flex;
|
|
259
277
|
align-items: center;
|
|
260
|
-
gap:
|
|
278
|
+
gap: 8px;
|
|
261
279
|
min-width: 0;
|
|
262
280
|
flex: 1;
|
|
263
281
|
}
|
|
264
282
|
|
|
265
283
|
.itemIcon {
|
|
266
|
-
width:
|
|
267
|
-
height:
|
|
284
|
+
width: 14px;
|
|
285
|
+
height: 14px;
|
|
268
286
|
flex: none;
|
|
269
|
-
color: var(--dsw-alias-label-tertiary);
|
|
287
|
+
color: var(--dsw-alias-label-tertiary, #94a3b8);
|
|
270
288
|
}
|
|
271
289
|
|
|
272
290
|
.currentBranch .itemIcon {
|
|
273
|
-
color: var(--dsw-alias-state-business-primary);
|
|
291
|
+
color: var(--dsw-alias-state-business-primary, #2563eb);
|
|
274
292
|
}
|
|
275
293
|
|
|
276
294
|
.itemText {
|
|
@@ -280,15 +298,15 @@
|
|
|
280
298
|
}
|
|
281
299
|
|
|
282
300
|
.checkMark {
|
|
283
|
-
width:
|
|
284
|
-
height:
|
|
285
|
-
color: var(--dsw-alias-state-business-primary);
|
|
301
|
+
width: 15px;
|
|
302
|
+
height: 15px;
|
|
303
|
+
color: var(--dsw-alias-state-business-primary, #2563eb);
|
|
286
304
|
flex: none;
|
|
287
305
|
}
|
|
288
306
|
|
|
289
307
|
.emptyTip {
|
|
290
|
-
padding:
|
|
308
|
+
padding: 20px 8px;
|
|
291
309
|
text-align: center;
|
|
292
|
-
color: var(--dsw-alias-label-tertiary);
|
|
310
|
+
color: var(--dsw-alias-label-tertiary, #94a3b8);
|
|
293
311
|
font-size: 12px;
|
|
294
312
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Status bar Git branch pill and popover branch switcher (
|
|
2
|
+
* Status bar Git branch pill and popover branch switcher (Clean & Elegant UI).
|
|
3
3
|
* Injected into the 'conversation.composer.dock' slot at order: -1.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -28,40 +28,21 @@ function IconBranchOutlineRegular({ className }: { className?: string }): React.
|
|
|
28
28
|
|
|
29
29
|
function IconCheckOutlineRegular({ className }: { className?: string }): React.ReactElement {
|
|
30
30
|
return (
|
|
31
|
-
<svg className={className} width="
|
|
31
|
+
<svg className={className} width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
|
|
32
32
|
<polyline points="3 8 7 12 13 4" />
|
|
33
33
|
</svg>
|
|
34
34
|
)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function IconPlusOutlineRegular({ className }: { className?: string }): React.ReactElement {
|
|
38
|
-
return (
|
|
39
|
-
<svg className={className} width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
40
|
-
<line x1="8" y1="3" x2="8" y2="13" />
|
|
41
|
-
<line x1="3" y1="8" x2="13" y2="8" />
|
|
42
|
-
</svg>
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
37
|
function IconRefreshOutlineRegular({ className }: { className?: string }): React.ReactElement {
|
|
47
38
|
return (
|
|
48
|
-
<svg className={className} width="
|
|
39
|
+
<svg className={className} width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
|
|
49
40
|
<path d="M2.5 8a5.5 5.5 0 1 0 1.6-3.9L2 6" />
|
|
50
41
|
<path d="M2 2v4h4" />
|
|
51
42
|
</svg>
|
|
52
43
|
)
|
|
53
44
|
}
|
|
54
45
|
|
|
55
|
-
function IconSearchOutlineRegular({ className }: { className?: string }): React.ReactElement {
|
|
56
|
-
return (
|
|
57
|
-
<svg className={className} width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
|
|
58
|
-
<circle cx="7" cy="7" r="4.5" />
|
|
59
|
-
<line x1="10.5" y1="10.5" x2="14" y2="14" />
|
|
60
|
-
</svg>
|
|
61
|
-
)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
46
|
export interface GitBranchPillProps {
|
|
66
47
|
getStatus?: ((sessionId?: string) => Promise<GitStatusSummary>) | undefined
|
|
67
48
|
getBranches?: ((sessionId?: string) => Promise<GitBranchesSummary>) | undefined
|
|
@@ -123,8 +104,8 @@ export const GitBranchPill = memo(function GitBranchPill({
|
|
|
123
104
|
if (!anchorRef.current) return
|
|
124
105
|
const rect = anchorRef.current.getBoundingClientRect()
|
|
125
106
|
setPopoverPos({
|
|
126
|
-
bottom: window.innerHeight - rect.top +
|
|
127
|
-
left: Math.max(
|
|
107
|
+
bottom: window.innerHeight - rect.top + 8,
|
|
108
|
+
left: Math.max(12, Math.min(rect.left, window.innerWidth - 340)),
|
|
128
109
|
})
|
|
129
110
|
}, [])
|
|
130
111
|
|
|
@@ -220,7 +201,7 @@ export const GitBranchPill = memo(function GitBranchPill({
|
|
|
220
201
|
return null
|
|
221
202
|
}
|
|
222
203
|
|
|
223
|
-
const currentBranchName = status?.branch || '
|
|
204
|
+
const currentBranchName = status?.branch || 'main'
|
|
224
205
|
|
|
225
206
|
return (
|
|
226
207
|
<span ref={anchorRef} className={css.anchor} data-composer-stat="git-branch">
|
|
@@ -246,7 +227,6 @@ export const GitBranchPill = memo(function GitBranchPill({
|
|
|
246
227
|
>
|
|
247
228
|
<div className={css.header}>
|
|
248
229
|
<div className={css.searchRow}>
|
|
249
|
-
<IconSearchOutlineRegular className={css.searchIcon} />
|
|
250
230
|
<input
|
|
251
231
|
autoFocus
|
|
252
232
|
className={css.searchInput}
|
|
@@ -259,18 +239,15 @@ export const GitBranchPill = memo(function GitBranchPill({
|
|
|
259
239
|
<div className={css.actionBar}>
|
|
260
240
|
<button
|
|
261
241
|
type="button"
|
|
262
|
-
className={css.
|
|
263
|
-
title="新建分支"
|
|
242
|
+
className={css.toolBtnPrimary}
|
|
264
243
|
onClick={() => { setCreatingBranch(prev => !prev) }}
|
|
265
244
|
>
|
|
266
|
-
<
|
|
267
|
-
<span>新建分支</span>
|
|
245
|
+
<span>+ 新建分支</span>
|
|
268
246
|
</button>
|
|
269
247
|
<div className={css.toolBtnGroup}>
|
|
270
248
|
<button
|
|
271
249
|
type="button"
|
|
272
250
|
className={css.toolBtn}
|
|
273
|
-
title="拉取 (Pull)"
|
|
274
251
|
onClick={() => { void handlePull() }}
|
|
275
252
|
>
|
|
276
253
|
Pull
|
|
@@ -278,7 +255,6 @@ export const GitBranchPill = memo(function GitBranchPill({
|
|
|
278
255
|
<button
|
|
279
256
|
type="button"
|
|
280
257
|
className={css.toolBtn}
|
|
281
|
-
title="推送 (Push)"
|
|
282
258
|
onClick={() => { void handlePush() }}
|
|
283
259
|
>
|
|
284
260
|
Push
|
|
@@ -325,32 +301,29 @@ export const GitBranchPill = memo(function GitBranchPill({
|
|
|
325
301
|
<IconBranchOutlineRegular className={css.itemIcon} />
|
|
326
302
|
<span className={css.itemText}>{b.name}</span>
|
|
327
303
|
</div>
|
|
328
|
-
{b.isCurrent
|
|
329
|
-
<IconCheckOutlineRegular className={css.checkMark} />
|
|
330
|
-
) : (
|
|
331
|
-
b.ahead !== undefined && b.ahead > 0 && <span className={css.badge}>↑{b.ahead}</span>
|
|
332
|
-
)}
|
|
304
|
+
{b.isCurrent && <IconCheckOutlineRegular className={css.checkMark} />}
|
|
333
305
|
</button>
|
|
334
306
|
))}
|
|
335
307
|
|
|
336
308
|
{/* Remote Branches */}
|
|
337
309
|
{filteredRemote.length > 0 && (
|
|
338
310
|
<>
|
|
339
|
-
<div className={css.groupLabel}
|
|
340
|
-
远程分支 ({filteredRemote.length})
|
|
341
|
-
</div>
|
|
311
|
+
<div className={css.groupLabel}>远程分支 ({filteredRemote.length})</div>
|
|
342
312
|
{filteredRemote.map(b => (
|
|
343
313
|
<button
|
|
344
314
|
key={b.name}
|
|
345
315
|
type="button"
|
|
346
|
-
className={css.branchItem}
|
|
316
|
+
className={`${css.branchItem} ${b.isCurrent ? css.currentBranch : ''}`}
|
|
347
317
|
disabled={switching}
|
|
348
|
-
onClick={() => {
|
|
318
|
+
onClick={() => {
|
|
319
|
+
if (!b.isCurrent) void handleCheckout(b.name)
|
|
320
|
+
}}
|
|
349
321
|
>
|
|
350
322
|
<div className={css.branchItemLeft}>
|
|
351
323
|
<IconBranchOutlineRegular className={css.itemIcon} />
|
|
352
324
|
<span className={css.itemText}>{b.name}</span>
|
|
353
325
|
</div>
|
|
326
|
+
{b.isCurrent && <IconCheckOutlineRegular className={css.checkMark} />}
|
|
354
327
|
</button>
|
|
355
328
|
))}
|
|
356
329
|
</>
|
package/src/client/locales.ts
CHANGED
|
@@ -6,14 +6,14 @@ export const NS = 'gitView'
|
|
|
6
6
|
|
|
7
7
|
export const zh = {
|
|
8
8
|
'type.label': 'Git',
|
|
9
|
-
'guide.title': 'Git
|
|
10
|
-
'guide.description': '
|
|
9
|
+
'guide.title': 'Git 源代码管理',
|
|
10
|
+
'guide.description': '查看项目代码变更、分支、提交历史与代码对比',
|
|
11
11
|
'shortcut.noSession': '没有激活的会话',
|
|
12
12
|
'tabs.changes': '更改',
|
|
13
13
|
'tabs.history': '提交历史',
|
|
14
|
-
'tabs.tree': '
|
|
15
|
-
'tabs.branches': '
|
|
16
|
-
'tabs.tags': '
|
|
14
|
+
'tabs.tree': '提交图谱',
|
|
15
|
+
'tabs.branches': '分支',
|
|
16
|
+
'tabs.tags': '标签',
|
|
17
17
|
'actions.refresh': '刷新状态',
|
|
18
18
|
'actions.viewDiff': '查看差异',
|
|
19
19
|
'actions.closeDiff': '收起差异',
|
|
@@ -27,68 +27,68 @@ export const zh = {
|
|
|
27
27
|
'actions.checkout': '检出分支',
|
|
28
28
|
'actions.newBranch': '新建分支',
|
|
29
29
|
'actions.fetch': '获取远程',
|
|
30
|
-
'actions.pull': '拉取',
|
|
31
|
-
'actions.push': '推送',
|
|
32
|
-
'commit.placeholder': '
|
|
30
|
+
'actions.pull': '拉取 (Pull)',
|
|
31
|
+
'actions.push': '推送 (Push)',
|
|
32
|
+
'commit.placeholder': '提交说明信息 (Ctrl+Enter 提交)...',
|
|
33
33
|
'commit.emptyWarning': '请输入提交说明',
|
|
34
34
|
'commit.success': '提交成功',
|
|
35
|
-
'branch.filter': '
|
|
35
|
+
'branch.filter': '搜索或过滤分支...',
|
|
36
36
|
'branch.local': '本地分支',
|
|
37
37
|
'branch.remote': '远程分支',
|
|
38
38
|
'branch.current': '当前分支',
|
|
39
|
-
'branch.newPrompt': '
|
|
39
|
+
'branch.newPrompt': '新分支名称 (按 Enter 创建)...',
|
|
40
40
|
'branch.createAndCheckout': '创建并检出',
|
|
41
41
|
'tree.author': '作者',
|
|
42
42
|
'tree.date': '时间',
|
|
43
43
|
'tree.hash': '哈希',
|
|
44
44
|
'tree.changedFiles': '变更文件',
|
|
45
|
-
'tree.selectCommit': '
|
|
46
|
-
'status.clean': '
|
|
45
|
+
'tree.selectCommit': '选择一次提交以查看详情与代码差异',
|
|
46
|
+
'status.clean': '工作区干净,无未提交的更改',
|
|
47
47
|
'status.notRepo': '当前工作区不是 Git 仓库',
|
|
48
|
-
'status.staged': '
|
|
49
|
-
'status.unstaged': '
|
|
48
|
+
'status.staged': '暂存的更改',
|
|
49
|
+
'status.unstaged': '更改',
|
|
50
50
|
'status.untracked': '未跟踪文件',
|
|
51
51
|
'status.ahead': '领先 {count} 个提交',
|
|
52
52
|
'status.behind': '落后 {count} 个提交',
|
|
53
53
|
'diff.additions': '+{count}',
|
|
54
54
|
'diff.deletions': '-{count}',
|
|
55
55
|
'diff.empty': '无内容变动',
|
|
56
|
-
'tag.filter': '
|
|
56
|
+
'tag.filter': '过滤标签 (名称、Hash或提交说明)...',
|
|
57
57
|
'tag.newPrompt': '新建标签 (Tag)',
|
|
58
58
|
'tag.nameLabel': '标签名称',
|
|
59
|
-
'tag.namePlaceholder': '输入标签名称 (
|
|
60
|
-
'tag.targetCommitLabel': '目标 Commit Hash (
|
|
61
|
-
'tag.messageLabel': '
|
|
62
|
-
'tag.messagePrompt': '
|
|
59
|
+
'tag.namePlaceholder': '输入标签名称 (如 v1.0.0)...',
|
|
60
|
+
'tag.targetCommitLabel': '目标 Commit Hash (可选,默认 HEAD)',
|
|
61
|
+
'tag.messageLabel': '附注说明信息 (可选)',
|
|
62
|
+
'tag.messagePrompt': '请输入附注说明信息 (可选)...',
|
|
63
63
|
'tag.createBtn': '创建标签',
|
|
64
64
|
'tag.cancelBtn': '取消',
|
|
65
65
|
'tag.locateBtn': '在图谱中定位',
|
|
66
66
|
'tag.copyName': '复制标签名',
|
|
67
67
|
'tag.deleteBtn': '删除',
|
|
68
68
|
'tag.deleteConfirm': '确定要删除标签 "{name}" 吗?',
|
|
69
|
-
'tag.empty': '
|
|
70
|
-
'tag.annotated': '
|
|
71
|
-
'tag.locatedNotice': '已定位到标签 "{name}"
|
|
69
|
+
'tag.empty': '未找到任何 Git 标签',
|
|
70
|
+
'tag.annotated': '含附注',
|
|
71
|
+
'tag.locatedNotice': '已定位到标签 "{name}" 所在提交',
|
|
72
72
|
'actions.locate': '定位',
|
|
73
73
|
'tree.colGraph': '图谱',
|
|
74
|
-
'tree.colSubject': '
|
|
74
|
+
'tree.colSubject': '提交说明与分支引用',
|
|
75
75
|
'tree.colAuthor': '作者',
|
|
76
76
|
'tree.colTime': '时间',
|
|
77
77
|
'tree.colSha': 'Commit SHA',
|
|
78
78
|
'tree.searchPlaceholder': '搜索提交说明、SHA 或作者...',
|
|
79
|
-
'tree.filterAll': '
|
|
80
|
-
'tree.filterMainline': '
|
|
79
|
+
'tree.filterAll': '全部提交',
|
|
80
|
+
'tree.filterMainline': '主线分支',
|
|
81
81
|
'detail.title': '提交详情 (COMMIT DETAILS)',
|
|
82
|
-
'detail.references': '
|
|
83
|
-
'detail.author': '
|
|
82
|
+
'detail.references': '分支引用 (REFERENCES)',
|
|
83
|
+
'detail.author': '提交作者 (Author)',
|
|
84
84
|
'detail.date': '提交时间 (Date)',
|
|
85
85
|
'detail.parent': '父级提交 (Parent)',
|
|
86
86
|
'detail.checkout': '检出分支 (Checkout)',
|
|
87
|
-
'detail.createBranchOrTag': '
|
|
88
|
-
'footer.showingCount': '
|
|
87
|
+
'detail.createBranchOrTag': '从此检出分支 / 标签',
|
|
88
|
+
'footer.showingCount': '显示 {count} 条提交 (共 {total} 条)',
|
|
89
89
|
'footer.loadMore': '加载更多',
|
|
90
|
-
'footer.syncNormal': '
|
|
91
|
-
'footer.ahead': '
|
|
90
|
+
'footer.syncNormal': '分支已与远程同步',
|
|
91
|
+
'footer.ahead': '领先远程 {count} 个提交',
|
|
92
92
|
'footer.behind': '落后远程 {count} 个提交',
|
|
93
93
|
} satisfies Record<string, string>
|
|
94
94
|
|