Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit22c5e84

Browse files
authored
fix: handle health status when displaying task apps (#18675)
Previously, we displayed apps in iframes on the task page withoutwaiting for them to initialize. This would result in 502 errors shown tothe user. This PR makes sure that we only display the app after itinitializes.### Before<img width="1920" alt="Screenshot 2025-06-30 at 14 59 07 (2)"src="https://github.com/user-attachments/assets/63564ac9-abce-4a0c-b58e-b988772fae82"/>
1 parentb7cb275 commit22c5e84

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

‎site/src/pages/TaskPage/TaskAppIframe.tsx‎

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
DropdownMenuItem,
77
DropdownMenuTrigger,
88
}from"components/DropdownMenu/DropdownMenu";
9+
import{Spinner}from"components/Spinner/Spinner";
910
import{EllipsisVertical,ExternalLinkIcon,HouseIcon}from"lucide-react";
1011
import{useAppLink}from"modules/apps/useAppLink";
1112
importtype{Task}from"modules/tasks/tasks";
@@ -97,14 +98,31 @@ export const TaskAppIFrame: FC<TaskAppIFrameProps> = ({
9798
</div>
9899
)}
99100

100-
<iframe
101-
ref={frameRef}
102-
src={frameSrc}
103-
title={link.label}
104-
loading="eager"
105-
className={"w-full h-full border-0"}
106-
allow="clipboard-read; clipboard-write"
107-
/>
101+
{app.health==="healthy"||
102+
app.health==="disabled"||
103+
app.health==="unhealthy" ?(
104+
<iframe
105+
ref={frameRef}
106+
src={frameSrc}
107+
title={link.label}
108+
loading="eager"
109+
className={"w-full h-full border-0"}
110+
allow="clipboard-read; clipboard-write"
111+
/>
112+
) :app.health==="initializing" ?(
113+
<divclassName="w-full h-full flex items-center justify-center">
114+
<Spinnerloading/>
115+
</div>
116+
) :(
117+
<divclassName="w-full h-full flex flex-col items-center justify-center">
118+
<h3className="m-0 font-medium text-content-primary text-base">
119+
Error
120+
</h3>
121+
<spanclassName="text-content-secondary text-sm">
122+
The app is in an unknown health state.
123+
</span>
124+
</div>
125+
)}
108126
</div>
109127
);
110128
};

‎site/src/pages/TaskPage/TaskApps.tsx‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
DropdownMenuTrigger,
88
}from"components/DropdownMenu/DropdownMenu";
99
import{ExternalImage}from"components/ExternalImage/ExternalImage";
10+
import{InfoTooltip}from"components/InfoTooltip/InfoTooltip";
1011
import{ChevronDownIcon,LayoutGridIcon}from"lucide-react";
1112
import{useAppLink}from"modules/apps/useAppLink";
1213
importtype{Task}from"modules/tasks/tasks";
@@ -165,6 +166,13 @@ const TaskAppTab: FC<TaskAppTabProps> = ({ task, app, active, onClick }) => {
165166
<RouterLinkto={link.href}onClick={onClick}>
166167
{app.icon ?<ExternalImagesrc={app.icon}/> :<LayoutGridIcon/>}
167168
{link.label}
169+
{app.health==="unhealthy"&&(
170+
<InfoTooltip
171+
title="This app is unhealthy."
172+
message="The health check failed."
173+
type="warning"
174+
/>
175+
)}
168176
</RouterLink>
169177
</Button>
170178
);

‎site/src/pages/TaskPage/TaskPage.stories.tsx‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,33 @@ export const SidebarAppHealthy: Story = {
176176
},
177177
};
178178

179+
constmainAppHealthStory=(health:WorkspaceApp["health"])=>({
180+
beforeEach:()=>{
181+
spyOn(data,"fetchTask").mockResolvedValue({
182+
prompt:"Create competitors page",
183+
workspace:{
184+
...MockWorkspace,
185+
latest_build:{
186+
...MockWorkspace.latest_build,
187+
resources:mockResources({
188+
claudeCodeAppOverrides:{
189+
health,
190+
},
191+
}),
192+
},
193+
},
194+
});
195+
},
196+
});
197+
198+
exportconstMainAppHealthy:Story=mainAppHealthStory("healthy");
199+
exportconstMainAppInitializing:Story=mainAppHealthStory("initializing");
200+
exportconstMainAppUnhealthy:Story=mainAppHealthStory("unhealthy");
201+
exportconstMainAppHealthDisabled:Story=mainAppHealthStory("disabled");
202+
exportconstMainAppHealthUnknown:Story=mainAppHealthStory(
203+
"unknown"asunknownasWorkspaceApp["health"],
204+
);
205+
179206
exportconstBuildNoAITask:Story={
180207
beforeEach:()=>{
181208
spyOn(data,"fetchTask").mockImplementation(()=>{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp