Skip to content

Commit b8c007f

Browse files
committed
Refactor ProjectSessionDetailPage component for improved readability
This update includes minor formatting adjustments for better code clarity, such as consistent indentation and spacing. The legacy `handleEndSession` function has been removed, and the code structure has been streamlined to enhance maintainability. These changes contribute to a cleaner and more organized component layout.
1 parent 16a99ee commit b8c007f

File tree

1 file changed

+103
-117
lines changed
  • components/frontend/src/app/projects/[name]/sessions/[sessionName]

1 file changed

+103
-117
lines changed

components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx

Lines changed: 103 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ export default function ProjectSessionDetailPage({
225225

226226
// Track the current Langfuse trace ID for feedback association
227227
const [langfuseTraceId, setLangfuseTraceId] = useState<string | null>(null);
228-
228+
229229
// AG-UI streaming hook - replaces useSessionMessages and useSendChatMessage
230230
// Note: autoConnect is intentionally false to avoid SSR hydration mismatch
231231
// Connection is triggered manually in useEffect after client hydration
@@ -693,12 +693,12 @@ export default function ProjectSessionDetailPage({
693693
seenRepos.add(repoName);
694694

695695
// Repos are cloned to /workspace/repos/{name}
696-
options.push({
697-
type: "repo",
698-
name: repoName,
696+
options.push({
697+
type: "repo",
698+
name: repoName,
699699
path: `repos/${repoName}`,
700-
});
701700
});
701+
});
702702

703703
if (workflowManagement.activeWorkflow && session?.spec?.activeWorkflow) {
704704
const workflowName =
@@ -1319,20 +1319,6 @@ export default function ProjectSessionDetailPage({
13191319
// LEGACY: Old handleInterrupt removed - now using aguiInterrupt from useAGUIStream
13201320
// which calls the proper AG-UI interrupt endpoint that signals Claude SDK
13211321

1322-
const handleEndSession = () => {
1323-
// Use stop API to end the session
1324-
stopMutation.mutate(
1325-
{ projectName, sessionName, data: { reason: "end_session" } },
1326-
{
1327-
onSuccess: () => successToast("Session ended successfully"),
1328-
onError: (err) =>
1329-
errorToast(
1330-
err instanceof Error ? err.message : "Failed to end session",
1331-
),
1332-
},
1333-
);
1334-
};
1335-
13361322
// Loading state
13371323
if (isLoading || !projectName || !sessionName) {
13381324
return (
@@ -1466,36 +1452,36 @@ export default function ProjectSessionDetailPage({
14661452

14671453
{/* Mobile: Options menu button (below header border) - always show */}
14681454
{session && (
1469-
<div className="md:hidden px-6 py-1 bg-card border-b">
1470-
<Button
1471-
variant="outline"
1472-
size="sm"
1473-
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
1474-
className="h-8 w-8 p-0"
1475-
>
1476-
<SlidersHorizontal className="h-4 w-4" />
1477-
</Button>
1478-
</div>
1455+
<div className="md:hidden px-6 py-1 bg-card border-b">
1456+
<Button
1457+
variant="outline"
1458+
size="sm"
1459+
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
1460+
className="h-8 w-8 p-0"
1461+
>
1462+
<SlidersHorizontal className="h-4 w-4" />
1463+
</Button>
1464+
</div>
14791465
)}
14801466

14811467
{/* Main content area */}
14821468
<div className="flex-grow overflow-hidden bg-card">
14831469
<div className="h-full relative">
14841470
{/* Mobile sidebar overlay */}
14851471
{mobileMenuOpen && (
1486-
<div
1472+
<div
14871473
className="fixed inset-0 bg-background/80 backdrop-blur-sm z-40 md:hidden"
14881474
onClick={() => setMobileMenuOpen(false)}
14891475
/>
14901476
)}
14911477

14921478
{/* Mobile Left Column (overlay) */}
14931479
{session && mobileMenuOpen && (
1494-
<div className={cn(
1480+
<div className={cn(
14951481
"fixed left-0 top-16 z-50 shadow-lg flex flex-col md:hidden",
14961482
"w-[400px] h-[calc(100vh-4rem)] pt-6 pl-6 pr-6 bg-card relative",
1497-
phase !== "Running" && "pointer-events-none"
1498-
)}>
1483+
phase !== "Running" && "pointer-events-none"
1484+
)}>
14991485
{/* Backdrop blur layer for entire sidebar */}
15001486
{phase !== "Running" && (
15011487
<div className={cn(
@@ -1725,7 +1711,7 @@ export default function ProjectSessionDetailPage({
17251711
>
17261712
<SelectTrigger className="w-[300px] h-auto min-h-[2.5rem] py-2.5 overflow-visible">
17271713
<div className="flex items-center gap-2 flex-wrap w-full pr-6 overflow-visible">
1728-
<SelectValue />
1714+
<SelectValue />
17291715
</div>
17301716
</SelectTrigger>
17311717
<SelectContent>
@@ -1755,34 +1741,34 @@ export default function ProjectSessionDetailPage({
17551741
}
17561742

17571743
return (
1758-
<SelectItem
1759-
key={`${opt.type}:${opt.path}`}
1760-
value={`${opt.type}:${opt.path}`}
1744+
<SelectItem
1745+
key={`${opt.type}:${opt.path}`}
1746+
value={`${opt.type}:${opt.path}`}
17611747
className="py-2"
1762-
>
1748+
>
17631749
<div className="flex items-center gap-2 flex-wrap w-full">
1764-
{opt.type === "artifacts" && (
1765-
<Folder className="h-3 w-3" />
1766-
)}
1767-
{opt.type === "file-uploads" && (
1768-
<CloudUpload className="h-3 w-3" />
1769-
)}
1770-
{opt.type === "repo" && (
1771-
<GitBranch className="h-3 w-3" />
1772-
)}
1773-
{opt.type === "workflow" && (
1774-
<Sparkles className="h-3 w-3" />
1775-
)}
1776-
<span className="text-xs">
1777-
{opt.name}
1778-
</span>
1750+
{opt.type === "artifacts" && (
1751+
<Folder className="h-3 w-3" />
1752+
)}
1753+
{opt.type === "file-uploads" && (
1754+
<CloudUpload className="h-3 w-3" />
1755+
)}
1756+
{opt.type === "repo" && (
1757+
<GitBranch className="h-3 w-3" />
1758+
)}
1759+
{opt.type === "workflow" && (
1760+
<Sparkles className="h-3 w-3" />
1761+
)}
1762+
<span className="text-xs">
1763+
{opt.name}
1764+
</span>
17791765
{branchName && (
17801766
<Badge variant="outline" className="text-xs px-1.5 py-0.5 max-w-full !whitespace-normal !overflow-visible break-words bg-blue-50 dark:bg-blue-950 border-blue-200 dark:border-blue-800">
17811767
{branchName}
17821768
</Badge>
17831769
)}
1784-
</div>
1785-
</SelectItem>
1770+
</div>
1771+
</SelectItem>
17861772
);
17871773
})}
17881774
</SelectContent>
@@ -1900,12 +1886,12 @@ export default function ProjectSessionDetailPage({
19001886
nodes={directoryFiles.map(
19011887
(item): FileTreeNode => {
19021888
const node: FileTreeNode = {
1903-
name: item.name,
1904-
path: item.path,
1905-
type: item.isDir ? "folder" : "file",
1906-
sizeKb: item.size
1907-
? item.size / 1024
1908-
: undefined,
1889+
name: item.name,
1890+
path: item.path,
1891+
type: item.isDir ? "folder" : "file",
1892+
sizeKb: item.size
1893+
? item.size / 1024
1894+
: undefined,
19091895
};
19101896

19111897
// Don't add branch badges to individual files/folders
@@ -1956,18 +1942,18 @@ export default function ProjectSessionDetailPage({
19561942
<span className="text-muted-foreground/50">(local only)</span>
19571943
</div>
19581944
</div>
1959-
<Button
1960-
onClick={() => setRemoteDialogOpen(true)}
1961-
size="sm"
1962-
variant="outline"
1945+
<Button
1946+
onClick={() => setRemoteDialogOpen(true)}
1947+
size="sm"
1948+
variant="outline"
19631949
className="w-full"
19641950
disabled={!githubConfigured}
1965-
>
1951+
>
19661952
<Cloud className="mr-2 h-3 w-3" />
19671953
Configure Remote
1968-
</Button>
1969-
</div>
1970-
) : (
1954+
</Button>
1955+
</div>
1956+
) : (
19711957
/* State 3: Has Git + Remote */
19721958
<div className="border rounded-md px-2 py-1.5 space-y-1">
19731959
{/* Remote Repository */}
@@ -1987,9 +1973,9 @@ export default function ProjectSessionDetailPage({
19871973
<GitBranch className="h-3 w-3 flex-shrink-0 text-muted-foreground" />
19881974
<span className="text-muted-foreground">
19891975
{currentBranch}
1990-
</span>
1991-
</div>
1992-
</div>
1976+
</span>
1977+
</div>
1978+
</div>
19931979
)}
19941980
</div>
19951981
</div>
@@ -1998,7 +1984,7 @@ export default function ProjectSessionDetailPage({
19981984
</Accordion>
19991985
</div>
20001986
</div>
2001-
)}
1987+
)}
20021988

20031989
{/* Floating show button when left panel is hidden (desktop only) */}
20041990
{!leftPanelVisible && !mobileMenuOpen && (
@@ -2226,53 +2212,53 @@ export default function ProjectSessionDetailPage({
22262212
</div>
22272213
)}
22282214
<div className="flex flex-col flex-1 overflow-hidden">
2229-
<FeedbackProvider
2230-
projectName={projectName}
2231-
sessionName={sessionName}
2232-
username={currentUser?.username || currentUser?.displayName || "anonymous"}
2233-
initialPrompt={session?.spec?.initialPrompt}
2234-
activeWorkflow={workflowManagement.activeWorkflow || undefined}
2235-
messages={streamMessages}
2236-
traceId={langfuseTraceId || undefined}
2237-
messageFeedback={aguiState.messageFeedback}
2238-
>
2239-
<MessagesTab
2240-
session={session}
2241-
streamMessages={streamMessages}
2242-
chatInput={chatInput}
2243-
setChatInput={setChatInput}
2244-
onSendChat={() => Promise.resolve(sendChat())}
2245-
onInterrupt={aguiInterrupt}
2246-
onGoToResults={() => {}}
2247-
onContinue={handleContinue}
2248-
workflowMetadata={workflowMetadata}
2249-
onCommandClick={handleCommandClick}
2250-
isRunActive={isRunActive}
2251-
showWelcomeExperience={!["Completed", "Failed", "Stopped", "Stopping"].includes(session?.status?.phase || "")}
2252-
activeWorkflow={workflowManagement.activeWorkflow}
2253-
userHasInteracted={userHasInteracted}
2254-
queuedMessages={sessionQueue.messages}
2255-
hasRealMessages={hasRealMessages}
2256-
welcomeExperienceComponent={
2257-
<WelcomeExperience
2258-
ootbWorkflows={ootbWorkflows}
2259-
onWorkflowSelect={handleWelcomeWorkflowSelect}
2260-
onUserInteraction={() => setUserHasInteracted(true)}
2261-
userHasInteracted={userHasInteracted}
2262-
sessionPhase={session?.status?.phase}
2263-
hasRealMessages={hasRealMessages}
2264-
onLoadWorkflow={() => setCustomWorkflowDialogOpen(true)}
2265-
selectedWorkflow={workflowManagement.selectedWorkflow}
2266-
/>
2267-
}
2268-
/>
2269-
</FeedbackProvider>
2215+
<FeedbackProvider
2216+
projectName={projectName}
2217+
sessionName={sessionName}
2218+
username={currentUser?.username || currentUser?.displayName || "anonymous"}
2219+
initialPrompt={session?.spec?.initialPrompt}
2220+
activeWorkflow={workflowManagement.activeWorkflow || undefined}
2221+
messages={streamMessages}
2222+
traceId={langfuseTraceId || undefined}
2223+
messageFeedback={aguiState.messageFeedback}
2224+
>
2225+
<MessagesTab
2226+
session={session}
2227+
streamMessages={streamMessages}
2228+
chatInput={chatInput}
2229+
setChatInput={setChatInput}
2230+
onSendChat={() => Promise.resolve(sendChat())}
2231+
onInterrupt={aguiInterrupt}
2232+
onGoToResults={() => {}}
2233+
onContinue={handleContinue}
2234+
workflowMetadata={workflowMetadata}
2235+
onCommandClick={handleCommandClick}
2236+
isRunActive={isRunActive}
2237+
showWelcomeExperience={!["Completed", "Failed", "Stopped", "Stopping"].includes(session?.status?.phase || "")}
2238+
activeWorkflow={workflowManagement.activeWorkflow}
2239+
userHasInteracted={userHasInteracted}
2240+
queuedMessages={sessionQueue.messages}
2241+
hasRealMessages={hasRealMessages}
2242+
welcomeExperienceComponent={
2243+
<WelcomeExperience
2244+
ootbWorkflows={ootbWorkflows}
2245+
onWorkflowSelect={handleWelcomeWorkflowSelect}
2246+
onUserInteraction={() => setUserHasInteracted(true)}
2247+
userHasInteracted={userHasInteracted}
2248+
sessionPhase={session?.status?.phase}
2249+
hasRealMessages={hasRealMessages}
2250+
onLoadWorkflow={() => setCustomWorkflowDialogOpen(true)}
2251+
selectedWorkflow={workflowManagement.selectedWorkflow}
2252+
/>
2253+
}
2254+
/>
2255+
</FeedbackProvider>
22702256
</div>
22712257
</CardContent>
22722258
</Card>
2273-
</div>
2274-
</div>
2275-
</div>
2259+
</div>
2260+
</div>
2261+
</div>
22762262
</div>
22772263

22782264
{/* Modals */}

0 commit comments

Comments
 (0)