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

Commitd4d311c

Browse files
committed
feat: add workspace build status to task page
1 parent5ed0c7a commitd4d311c

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
22
import{expect,spyOn,within}from"@storybook/test";
3+
import{API}from"api/api";
34
importtype{Workspace,WorkspaceApp}from"api/typesGenerated";
45
import{
56
MockFailedWorkspace,
67
MockStartingWorkspace,
78
MockStoppedWorkspace,
9+
MockTemplate,
810
MockWorkspace,
911
MockWorkspaceAgent,
1012
MockWorkspaceApp,
1113
MockWorkspaceAppStatus,
14+
MockWorkspaceBuildLogs,
1215
MockWorkspaceResource,
1316
mockApiError,
1417
}from"testHelpers/entities";
15-
import{withProxyProvider}from"testHelpers/storybook";
18+
import{withProxyProvider,withWebSocket}from"testHelpers/storybook";
1619
importTaskPage,{data}from"./TaskPage";
1720

1821
constmeta:Meta<typeofTaskPage>={
@@ -54,6 +57,33 @@ export const WaitingOnBuild: Story = {
5457
},
5558
};
5659

60+
exportconstWaitingOnBuildWithTemplate:Story={
61+
beforeEach:()=>{
62+
spyOn(API,"getTemplate").mockResolvedValue(MockTemplate);
63+
spyOn(data,"fetchTask").mockResolvedValue({
64+
prompt:"Create competitors page",
65+
workspace:MockStartingWorkspace,
66+
});
67+
},
68+
};
69+
70+
exportconstWaitingOnBuildWithLogs:Story={
71+
parameters:{
72+
decorators:[withWebSocket],
73+
webSocket:MockWorkspaceBuildLogs.map((log)=>({
74+
event:"message",
75+
data:JSON.stringify(log),
76+
})),
77+
},
78+
beforeEach:()=>{
79+
spyOn(API,"getTemplate").mockResolvedValue(MockTemplate);
80+
spyOn(data,"fetchTask").mockResolvedValue({
81+
prompt:"Create competitors page",
82+
workspace:MockStartingWorkspace,
83+
});
84+
},
85+
};
86+
5787
exportconstWaitingOnStatus:Story={
5888
beforeEach:()=>{
5989
spyOn(data,"fetchTask").mockResolvedValue({

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

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import{API}from"api/api";
22
import{getErrorDetail,getErrorMessage}from"api/errors";
3+
import{templateastemplateQueryOptions}from"api/queries/templates";
34
importtype{WorkspaceStatus}from"api/typesGenerated";
45
import{Button}from"components/Button/Button";
56
import{Loader}from"components/Loader/Loader";
67
import{Margins}from"components/Margins/Margins";
78
import{Spinner}from"components/Spinner/Spinner";
9+
import{useWorkspaceBuildLogs}from"hooks/useWorkspaceBuildLogs";
810
import{ArrowLeftIcon,RotateCcwIcon}from"lucide-react";
911
import{AI_PROMPT_PARAMETER_NAME,typeTask}from"modules/tasks/tasks";
1012
importtype{ReactNode}from"react";
@@ -14,6 +16,10 @@ import { useParams } from "react-router-dom";
1416
import{LinkasRouterLink}from"react-router-dom";
1517
import{ellipsizeText}from"utils/ellipsizeText";
1618
import{pageTitle}from"utils/page";
19+
import{
20+
ActiveTransition,
21+
WorkspaceBuildProgress,
22+
}from"../WorkspacePage/WorkspaceBuildProgress";
1723
import{TaskApps}from"./TaskApps";
1824
import{TaskSidebar}from"./TaskSidebar";
1925

@@ -32,6 +38,20 @@ const TaskPage = () => {
3238
refetchInterval:5_000,
3339
});
3440

41+
const{data:template}=useQuery({
42+
...templateQueryOptions(task?.workspace.template_id??""),
43+
enabled:Boolean(task),
44+
});
45+
46+
constwaitingStatuses:WorkspaceStatus[]=["starting","pending"];
47+
constshouldStreamBuildLogs=waitingStatuses.includes(
48+
task?.workspace.latest_build.status,
49+
);
50+
constbuildLogs=useWorkspaceBuildLogs(
51+
task?.workspace.latest_build.id??"",
52+
shouldStreamBuildLogs,
53+
);
54+
3555
if(error){
3656
return(
3757
<>
@@ -77,7 +97,6 @@ const TaskPage = () => {
7797
}
7898

7999
letcontent:ReactNode=null;
80-
constwaitingStatuses:WorkspaceStatus[]=["starting","pending"];
81100
constterminatedStatuses:WorkspaceStatus[]=[
82101
"canceled",
83102
"canceling",
@@ -88,17 +107,27 @@ const TaskPage = () => {
88107
];
89108

90109
if(waitingStatuses.includes(task.workspace.latest_build.status)){
110+
// If no template yet, use null values for an indeterminate progress bar.
111+
consttransition=(template&&
112+
ActiveTransition(template,task.workspace))||{P50:null,P95:null};
113+
constlastStage=buildLogs?.[buildLogs.length-1]?.stage;
91114
content=(
92-
<divclassName="w-full min-h-80 flex items-center justify-center">
115+
<divclassName="w-full min-h-80 flexflex-colitems-center justify-center gap-2">
93116
<divclassName="flex flex-col items-center">
94-
<SpinnerloadingclassName="mb-4"/>
95117
<h3className="m-0 font-medium text-content-primary text-base">
96118
Starting your workspace
97119
</h3>
98120
<spanclassName="text-content-secondary text-sm">
99121
This should take a few minutes
100122
</span>
101123
</div>
124+
{lastStage&&(
125+
<divclassName="text-content-secondary text-sm">{lastStage}</div>
126+
)}
127+
<WorkspaceBuildProgress
128+
workspace={task.workspace}
129+
transitionStats={transition}
130+
/>
102131
</div>
103132
);
104133
}elseif(task.workspace.latest_build.status==="failed"){
@@ -186,13 +215,8 @@ export const data = {
186215
constparameters=awaitAPI.getWorkspaceBuildParameters(
187216
workspace.latest_build.id,
188217
);
189-
constprompt=parameters.find(
190-
(p)=>p.name===AI_PROMPT_PARAMETER_NAME,
191-
)?.value;
192-
193-
if(!prompt){
194-
return;
195-
}
218+
constprompt=
219+
parameters.find((p)=>p.name===AI_PROMPT_PARAMETER_NAME)?.value??"";
196220

197221
return{
198222
workspace,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp