Skip to content

Commit 19ae345

Browse files
authored
feat: refactor CodegenSidebarEntry markup, add metadata and heads (#10164)
1 parent 413676a commit 19ae345

File tree

4 files changed

+120
-163
lines changed

4 files changed

+120
-163
lines changed

apps/desktop/src/components/codegen/CodegenPage.svelte

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import CodegenServiceMessage from '$components/codegen/CodegenServiceMessage.svelte';
1616
import CodegenSidebar from '$components/codegen/CodegenSidebar.svelte';
1717
import CodegenSidebarEntry from '$components/codegen/CodegenSidebarEntry.svelte';
18-
import CodegenSidebarEntryDisabled from '$components/codegen/CodegenSidebarEntryDisabled.svelte';
1918
import CodegenTodo from '$components/codegen/CodegenTodo.svelte';
2019
import ClaudeCheck from '$components/v3/ClaudeCheck.svelte';
2120
import appClickSvg from '$lib/assets/empty-state/app-click.svg?raw';
@@ -725,6 +724,7 @@
725724
commitCount={commits.length}
726725
lastInteractionTime={lastInteractionTime(events)}
727726
commits={commitsList}
727+
{totalHeads}
728728
>
729729
{#snippet branchIcon()}
730730
<BranchHeaderIcon {iconName} color={lineColor} small />
@@ -755,17 +755,6 @@
755755
{/snippet}
756756
{/snippet}
757757
</ReduxResult>
758-
{:else}
759-
{@const branch = stackService.branchByName(projectId, stackId, head)}
760-
<ReduxResult result={branch.current} {projectId} {stackId}>
761-
{#snippet children(branch, { projectId: _projectId, stackId: _stackId })}
762-
<CodegenSidebarEntryDisabled branchName={branch.name}>
763-
{#snippet branchIcon()}
764-
<BranchHeaderIcon iconName="branch-remote" color="var(--clr-text-3)" small />
765-
{/snippet}
766-
</CodegenSidebarEntryDisabled>
767-
{/snippet}
768-
</ReduxResult>
769758
{/if}
770759
{/snippet}
771760

Lines changed: 117 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { Badge, Icon, TimeAgo, Tooltip } from '@gitbutler/ui';
2+
import { Badge, Icon, TimeAgo, Tooltip, InfoButton } from '@gitbutler/ui';
33
import { slide } from 'svelte/transition';
44
import type { ClaudeStatus } from '$lib/codegen/types';
55
import type { Snippet } from 'svelte';
@@ -15,6 +15,7 @@
1515
commits: Snippet;
1616
onclick: (e: MouseEvent) => void;
1717
branchIcon: Snippet;
18+
totalHeads: number;
1819
};
1920
2021
const {
@@ -27,81 +28,96 @@
2728
lastInteractionTime,
2829
commits,
2930
onclick,
30-
branchIcon
31+
branchIcon,
32+
totalHeads
3133
}: Props = $props();
3234
3335
let isOpen = $state(false);
3436
</script>
3537

36-
<div class="sidebar-entry">
37-
<button class="sidebar-entry-header" class:selected type="button" {onclick}>
38-
{#if selected}
39-
<div class="entry-active-indicator" in:slide={{ axis: 'x', duration: 150 }}></div>
40-
{/if}
41-
<div class="sidebar-entry-header-left">
42-
{@render branchIcon()}
38+
<div class="codegen-entry-wrapper">
39+
<div class="codegen-entry">
40+
<button class="codegen-entry-header" class:selected type="button" {onclick}>
41+
{#if selected}
42+
<div class="active-indicator" in:slide={{ axis: 'x', duration: 150 }}></div>
43+
{/if}
44+
<div class="entry-header-content">
45+
{@render branchIcon()}
4346

44-
<p class="text-14 text-bold truncate full-width">{branchName}</p>
45-
{@render vibeIcon()}
46-
</div>
47+
<p class="text-14 text-bold truncate full-width">{branchName}</p>
48+
{@render vibeIcon()}
49+
</div>
4750

48-
{#if status !== 'disabled'}
49-
<div class="sidebar-entry-drawer__header-info text-12">
50-
<Tooltip text="Total tokens used and cost">
51-
<div class="flex gap-4 items-center">
52-
<p>{tokensUsed}</p>
53-
54-
<svg
55-
width="0.938rem"
56-
height="0.938rem"
57-
viewBox="0 0 15 15"
58-
fill="none"
59-
xmlns="http://www.w3.org/2000/svg"
60-
opacity="0.6"
61-
>
62-
<circle cx="7.5" cy="7.5" r="5.5" stroke="currentColor" stroke-width="1.5" />
63-
<circle
64-
cx="7.50015"
65-
cy="7.5"
66-
r="2.92106"
67-
transform="rotate(-45 7.50015 7.5)"
68-
stroke="currentColor"
69-
stroke-width="1.5"
70-
stroke-dasharray="2 1"
71-
/>
72-
</svg>
73-
74-
<div class="sidebar-entry-drawer__header-info__divider"></div>
75-
<p>${cost.toFixed(2)}</p>
51+
{#if status !== 'disabled'}
52+
<div class="entry-metadata text-12">
53+
<Tooltip text="Total tokens used and cost">
54+
<div class="flex gap-4 items-center">
55+
<p>{tokensUsed}</p>
56+
57+
<svg
58+
width="0.938rem"
59+
height="0.938rem"
60+
viewBox="0 0 15 15"
61+
fill="none"
62+
xmlns="http://www.w3.org/2000/svg"
63+
opacity="0.6"
64+
>
65+
<circle cx="7.5" cy="7.5" r="5.5" stroke="currentColor" stroke-width="1.5" />
66+
<circle
67+
cx="7.50015"
68+
cy="7.5"
69+
r="2.92106"
70+
transform="rotate(-45 7.50015 7.5)"
71+
stroke="currentColor"
72+
stroke-width="1.5"
73+
stroke-dasharray="2 1"
74+
/>
75+
</svg>
76+
77+
<div class="metadata-divider"></div>
78+
<p>${cost.toFixed(2)}</p>
79+
</div>
80+
</Tooltip>
81+
82+
{#if lastInteractionTime}
83+
<p class="text-11 last-interaction-time opacity-60">
84+
<TimeAgo date={lastInteractionTime} addSuffix />
85+
</p>
86+
{/if}
87+
</div>
88+
{/if}
89+
</button>
90+
91+
{#if commitCount > 0}
92+
<div class="commits-drawer">
93+
<button class="commits-drawer-header" onclick={() => (isOpen = !isOpen)} type="button">
94+
<div class="fold-icon" class:open={isOpen}>
95+
<Icon name="chevron-right" />
7696
</div>
77-
</Tooltip>
97+
<p class="text-13 text-semibold">Commits</p>
98+
<Badge kind="soft">{commitCount}</Badge>
99+
</button>
78100

79-
{#if lastInteractionTime}
80-
<p class="text-11 sidebar-entry-drawer__tima-ago opacity-60">
81-
<TimeAgo date={lastInteractionTime} addSuffix />
82-
</p>
101+
{#if isOpen}
102+
<div class="stack-v full-width" transition:slide|local={{ duration: 150, axis: 'y' }}>
103+
<div class="commits-list">
104+
{@render commits()}
105+
</div>
106+
</div>
83107
{/if}
84108
</div>
85109
{/if}
86-
</button>
110+
</div>
87111

88-
{#if commitCount > 0}
89-
<div class="sidebar-entry-drawer">
90-
<button class="sidebar-entry-drawer__header" onclick={() => (isOpen = !isOpen)} type="button">
91-
<div class="sidebar-entry-drawer__header__fold-icon" class:open={isOpen}>
92-
<Icon name="chevron-right" />
93-
</div>
94-
<p class="text-13 text-semibold">Commits</p>
95-
<Badge kind="soft">{commitCount}</Badge>
96-
</button>
97-
98-
{#if isOpen}
99-
<div class="stack-v full-width" transition:slide|local={{ duration: 150, axis: 'y' }}>
100-
<div class="sidebar-entry-drawer__commits">
101-
{@render commits()}
102-
</div>
103-
</div>
104-
{/if}
112+
{#if totalHeads > 1}
113+
<div class="entry-heads">
114+
<Icon name="stack" color="var(--clr-text-3)" />
115+
<p class="text-12 text-semibold full-width">{totalHeads - 1} more branches in stack</p>
116+
117+
<InfoButton>
118+
Currently GitButler doesn’t support multiple sessions for a stack. A session is applied only
119+
to the top branch.
120+
</InfoButton>
105121
</div>
106122
{/if}
107123
</div>
@@ -117,15 +133,23 @@
117133
{/snippet}
118134

119135
<style lang="postcss">
120-
.sidebar-entry {
136+
.codegen-entry-wrapper {
137+
display: flex;
138+
flex-direction: column;
139+
align-items: center;
140+
}
141+
142+
.codegen-entry {
143+
z-index: var(--z-ground);
144+
position: relative;
121145
flex-shrink: 0;
122146
width: 100%;
123147
overflow: hidden;
124148
border: 1px solid var(--clr-border-2);
125149
border-radius: var(--radius-ml);
126150
}
127151
128-
.sidebar-entry-header {
152+
.codegen-entry-header {
129153
display: flex;
130154
position: relative;
131155
flex-direction: column;
@@ -144,7 +168,7 @@
144168
}
145169
}
146170
147-
.sidebar-entry-header-left {
171+
.entry-header-content {
148172
display: flex;
149173
align-items: center;
150174
width: 100%;
@@ -161,29 +185,29 @@
161185
}
162186
163187
/* DRAWER */
164-
.sidebar-entry-drawer {
188+
.commits-drawer {
165189
display: flex;
166190
flex-direction: column;
167191
width: 100%;
168192
border-top: 1px solid var(--clr-border-2);
169193
}
170194
171-
.sidebar-entry-drawer__header {
195+
.commits-drawer-header {
172196
display: flex;
173197
align-items: center;
174198
width: 100%;
175199
padding: 10px 12px;
176200
gap: 6px;
177-
background-color: color-mix(in srgb, var(--clr-bg-2) 60%, transparent);
201+
background-color: var(--clr-bg-2);
178202
179203
&:hover {
180-
.sidebar-entry-drawer__header__fold-icon {
204+
.fold-icon {
181205
color: var(--clr-text-2);
182206
}
183207
}
184208
}
185209
186-
.sidebar-entry-drawer__header__fold-icon {
210+
.fold-icon {
187211
display: flex;
188212
color: var(--clr-text-3);
189213
transition:
@@ -195,7 +219,7 @@
195219
}
196220
}
197221
198-
.sidebar-entry-drawer__header-info {
222+
.entry-metadata {
199223
display: flex;
200224
align-items: center;
201225
justify-content: space-between;
@@ -205,35 +229,33 @@
205229
opacity: 0.7;
206230
}
207231
208-
.sidebar-entry-drawer__header-info__divider {
232+
.metadata-divider {
209233
width: 1px;
210234
height: 12px;
211235
margin: 0 4px;
212236
background-color: var(--clr-text-1);
213237
opacity: 0.3;
214238
}
215239
216-
.sidebar-entry-drawer__commits {
240+
.commits-list {
217241
display: flex;
218242
flex-direction: column;
219243
border-top: 1px solid var(--clr-border-2);
244+
background-color: var(--clr-bg-1);
220245
}
221246
222247
.vibe-icon {
223248
display: flex;
224249
225-
&.enabled {
226-
/* color: var(--clr-theme-pop-element); */
227-
}
228250
&.running {
229-
/* color: var(--clr-theme-pop-element); */
251+
color: var(--clr-theme-pop-element);
230252
}
231253
&.completed {
232-
/* color: var(--clr-theme-succ-element); */
254+
color: var(--clr-theme-succ-element);
233255
}
234256
}
235257
236-
.entry-active-indicator {
258+
.active-indicator {
237259
position: absolute;
238260
top: 12px;
239261
left: 0;
@@ -243,4 +265,19 @@
243265
border-radius: var(--radius-m);
244266
background-color: var(--clr-theme-pop-element);
245267
}
268+
269+
.entry-heads {
270+
display: flex;
271+
position: relative;
272+
align-items: center;
273+
width: calc(100% - 8px);
274+
padding: 12px 12px 10px;
275+
gap: 8px;
276+
transform: translateY(-4px);
277+
border: 1px solid var(--clr-border-3);
278+
border-radius: 0 0 var(--radius-ml) var(--radius-ml);
279+
background: linear-gradient(180deg, var(--clr-bg-2) 20%, var(--clr-bg-1) 200%);
280+
background-color: var(--clr-bg-2);
281+
color: var(--clr-text-2);
282+
}
246283
</style>

0 commit comments

Comments
 (0)