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

Commitcb7a768

Browse files
committed
feat: add workspace build status to task page
1 parent4fd0312 commitcb7a768

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
22
import{expect,spyOn,within}from"@storybook/test";
3+
import{API}from"api/api";
34
importtype{
45
Workspace,
56
WorkspaceApp,
@@ -9,14 +10,16 @@ import {
910
MockFailedWorkspace,
1011
MockStartingWorkspace,
1112
MockStoppedWorkspace,
13+
MockTemplate,
1214
MockWorkspace,
1315
MockWorkspaceAgent,
1416
MockWorkspaceApp,
1517
MockWorkspaceAppStatus,
18+
MockWorkspaceBuildLogs,
1619
MockWorkspaceResource,
1720
mockApiError,
1821
}from"testHelpers/entities";
19-
import{withProxyProvider}from"testHelpers/storybook";
22+
import{withProxyProvider,withWebSocket}from"testHelpers/storybook";
2023
importTaskPage,{data,WorkspaceDoesNotHaveAITaskError}from"./TaskPage";
2124

2225
constmeta:Meta<typeofTaskPage>={
@@ -59,6 +62,33 @@ export const WaitingOnBuild: Story = {
5962
},
6063
};
6164

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

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

Lines changed: 31 additions & 3 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{Workspace,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,19 @@ 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=
48+
task&&waitingStatuses.includes(task.workspace.latest_build.status);
49+
constbuildLogs=useWorkspaceBuildLogs(
50+
task?.workspace.latest_build.id??"",
51+
shouldStreamBuildLogs,
52+
);
53+
3554
if(error){
3655
return(
3756
<>
@@ -77,7 +96,6 @@ const TaskPage = () => {
7796
}
7897

7998
letcontent:ReactNode=null;
80-
constwaitingStatuses:WorkspaceStatus[]=["starting","pending"];
8199
constterminatedStatuses:WorkspaceStatus[]=[
82100
"canceled",
83101
"canceling",
@@ -88,17 +106,27 @@ const TaskPage = () => {
88106
];
89107

90108
if(waitingStatuses.includes(task.workspace.latest_build.status)){
109+
// If no template yet, use null values for an indeterminate progress bar.
110+
consttransition=(template&&
111+
ActiveTransition(template,task.workspace))||{P50:null,P95:null};
112+
constlastStage=buildLogs?.[buildLogs.length-1]?.stage;
91113
content=(
92-
<divclassName="w-full min-h-80 flex items-center justify-center">
114+
<divclassName="w-full min-h-80 flexflex-colitems-center justify-center gap-2">
93115
<divclassName="flex flex-col items-center">
94-
<SpinnerloadingclassName="mb-4"/>
95116
<h3className="m-0 font-medium text-content-primary text-base">
96117
Starting your workspace
97118
</h3>
98119
<spanclassName="text-content-secondary text-sm">
99120
This should take a few minutes
100121
</span>
101122
</div>
123+
{lastStage&&(
124+
<divclassName="text-content-secondary text-sm">{lastStage}</div>
125+
)}
126+
<WorkspaceBuildProgress
127+
workspace={task.workspace}
128+
transitionStats={transition}
129+
/>
102130
</div>
103131
);
104132
}elseif(task.workspace.latest_build.status==="failed"){

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp