Skip to content

Commit d63e0a1

Browse files
authored
Merge pull request #9816 from gitbutlerapp/refactor-claude-session-template
Refactor: centralize Claude session descriptor logic
2 parents 6f24b96 + 8f8c5ce commit d63e0a1

File tree

4 files changed

+65
-22
lines changed

4 files changed

+65
-22
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script lang="ts">
2+
import ReduxResult from '$components/ReduxResult.svelte';
3+
import { CLAUDE_CODE_SERVICE } from '$lib/codegen/claude';
4+
import { sessionMessage, type ClaudeSessionDetails } from '$lib/codegen/types';
5+
import { inject } from '@gitbutler/shared/context';
6+
import type { Snippet } from 'svelte';
7+
8+
type Props = {
9+
projectId: string;
10+
sessionId: string;
11+
fallback: Snippet;
12+
children: Snippet<[string]>;
13+
};
14+
15+
const { projectId, sessionId, children, fallback }: Props = $props();
16+
const claudeCodeService = inject(CLAUDE_CODE_SERVICE);
17+
const sessionDetails = $derived(claudeCodeService.sessionDetails(projectId, sessionId));
18+
</script>
19+
20+
{#snippet loading()}
21+
{@render fallback()}
22+
{/snippet}
23+
24+
{#snippet error()}
25+
{@render fallback()}
26+
{/snippet}
27+
28+
{#snippet resultChildren(sessionDetails: ClaudeSessionDetails)}
29+
{@const title = sessionMessage(sessionDetails) ?? sessionId}
30+
{@render children(title)}
31+
{/snippet}
32+
33+
<ReduxResult {projectId} result={sessionDetails.current} {loading} {error} children={resultChildren}
34+
></ReduxResult>

apps/desktop/src/components/Rule.svelte

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts">
2+
import ClaudeSessionDescriptor from '$components/ClaudeSessionDescriptor.svelte';
23
import ReduxResult from '$components/ReduxResult.svelte';
3-
import { CLAUDE_CODE_SERVICE } from '$lib/codegen/claude';
4-
import { sessionMessage } from '$lib/codegen/types';
54
import {
65
semanticTypeToString,
76
treeStatusToShortString,
@@ -26,7 +25,6 @@
2625
2726
const stackService = inject(STACK_SERVICE);
2827
const rulesService = inject(RULES_SERVICE);
29-
const claudeCodeService = inject(CLAUDE_CODE_SERVICE);
3028
3129
const [deleteRule, deletingRule] = rulesService.deleteWorkspaceRule;
3230
@@ -143,19 +141,14 @@
143141
{@const config = getFilterConfig(filter)}
144142

145143
{#if filter.type === 'claudeCodeSessionId'}
146-
{@const sessionDetails = claudeCodeService.sessionDetails(projectId, filter.subject)}
147-
<ReduxResult {projectId} result={sessionDetails.current}>
148-
{#snippet loading()}
144+
<ClaudeSessionDescriptor {projectId} sessionId={filter.subject}>
145+
{#snippet fallback()}
149146
{@render renderBasicPill(config)}
150147
{/snippet}
151-
{#snippet error()}
152-
{@render renderBasicPill(config)}
153-
{/snippet}
154-
{#snippet children(sessionDetails)}
155-
{@const title = sessionMessage(sessionDetails) ?? filter.subject}
156-
{@render renderSessionPill(`Code session: ${title}`, config.icon!, title)}
148+
{#snippet children(descriptor)}
149+
{@render renderSessionPill(`Code session: ${descriptor}`, config.icon!, descriptor)}
157150
{/snippet}
158-
</ReduxResult>
151+
</ClaudeSessionDescriptor>
159152
{:else if filter.type === 'fileChangeType'}
160153
{@render renderFileChangePill(config, filter.subject)}
161154
{:else}

apps/desktop/src/components/RuleFiltersEditor.svelte

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import ClaudeSessionDescriptor from '$components/ClaudeSessionDescriptor.svelte';
23
import NewRuleMenu from '$components/NewRuleMenu.svelte';
34
import {
45
type SemanticType,
@@ -17,12 +18,13 @@
1718
const FILE_STATUS_OPTIONS: FileStatus[] = ['addition', 'modification', 'deletion', 'rename'];
1819
1920
type Props = {
21+
projectId: string;
2022
initialFilterValues: Partial<RuleFilterMap>;
2123
addFilter: (type: RuleFilterType) => void;
2224
deleteFilter: (type: RuleFilterType) => void;
2325
};
2426
25-
const { initialFilterValues, addFilter, deleteFilter }: Props = $props();
27+
const { projectId, initialFilterValues, addFilter, deleteFilter }: Props = $props();
2628
2729
let addFilterButton = $state<HTMLDivElement>();
2830
let newFilterContextMenu = $state<NewRuleMenu>();
@@ -201,12 +203,25 @@
201203
{/snippet}
202204

203205
<!-- Claude Code Session ID -->
204-
{#snippet claudeCodeSessionIdFilter()}
205-
<Textbox value={claudeCodeSessionId} readonly>
206-
{#snippet customIconLeft()}
207-
<Icon name="ai" />
208-
{/snippet}
209-
</Textbox>
206+
{#snippet claudeCodeSessionIdFilter(sessionId: string)}
207+
<div class="rule__pill expand">
208+
<ClaudeSessionDescriptor {projectId} {sessionId}>
209+
{#snippet fallback()}
210+
<Textbox value={sessionId} readonly>
211+
{#snippet customIconLeft()}
212+
<Icon name="ai" />
213+
{/snippet}
214+
</Textbox>
215+
{/snippet}
216+
{#snippet children(descriptor)}
217+
<Textbox value={descriptor} readonly>
218+
{#snippet customIconLeft()}
219+
<Icon name="ai" />
220+
{/snippet}
221+
</Textbox>
222+
{/snippet}
223+
</ClaudeSessionDescriptor>
224+
</div>
210225
{/snippet}
211226

212227
<!-- This is the parent component,
@@ -221,8 +236,8 @@
221236
{@render fileChangeType()}
222237
{:else if type === 'semanticType'}
223238
{@render semanticTypeFilter()}
224-
{:else if type === 'claudeCodeSessionId'}
225-
{@render claudeCodeSessionIdFilter()}
239+
{:else if type === 'claudeCodeSessionId' && claudeCodeSessionId}
240+
{@render claudeCodeSessionIdFilter(claudeCodeSessionId)}
226241
{/if}
227242

228243
{#if type !== 'claudeCodeSessionId'}

apps/desktop/src/components/RulesList.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@
251251
<div class="rules-list__filters">
252252
<RuleFiltersEditor
253253
bind:this={ruleFiltersEditor}
254+
{projectId}
254255
initialFilterValues={draftRuleFilterInitialValues}
255256
addFilter={addDraftRuleFilter}
256257
deleteFilter={removeDraftRuleFilter}

0 commit comments

Comments
 (0)