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

Commitbc3b8d5

Browse files
1 parentb330c08 commitbc3b8d5

File tree

10 files changed

+676
-64
lines changed

10 files changed

+676
-64
lines changed

‎site/src/components/Table/Table.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*@see {@link https://ui.shadcn.com/docs/components/table}
44
*/
55

6+
import{typeVariantProps,cva}from"class-variance-authority";
67
import*asReactfrom"react";
78
import{cn}from"utils/cn";
89

@@ -60,15 +61,38 @@ const TableFooter = React.forwardRef<
6061
/>
6162
));
6263

64+
consttableRowVariants=cva(
65+
[
66+
"border-0 border-b border-solid border-border transition-colors",
67+
"data-[state=selected]:bg-muted",
68+
],
69+
{
70+
variants:{
71+
hover:{
72+
false:null,
73+
true:cn([
74+
"cursor-pointer hover:outline focus:outline outline-1 -outline-offset-1 outline-border-hover",
75+
"first:rounded-t-md last:rounded-b-md",
76+
]),
77+
},
78+
},
79+
defaultVariants:{
80+
hover:false,
81+
},
82+
},
83+
);
84+
6385
exportconstTableRow=React.forwardRef<
6486
HTMLTableRowElement,
65-
React.HTMLAttributes<HTMLTableRowElement>
66-
>(({ className, ...props},ref)=>(
87+
React.HTMLAttributes<HTMLTableRowElement>&
88+
VariantProps<typeoftableRowVariants>
89+
>(({ className, hover, ...props},ref)=>(
6790
<tr
6891
ref={ref}
6992
className={cn(
7093
"border-0 border-b border-solid border-border transition-colors",
7194
"data-[state=selected]:bg-muted",
95+
tableRowVariants({ hover}),
7296
className,
7397
)}
7498
{...props}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
importtype{WorkspaceAppStatus}from"api/typesGenerated";
2+
import{Spinner}from"components/Spinner/Spinner";
3+
import{
4+
CircleAlertIcon,
5+
CircleCheckIcon,
6+
HourglassIcon,
7+
TriangleAlertIcon,
8+
}from"lucide-react";
9+
importtype{FC}from"react";
10+
import{cn}from"utils/cn";
11+
12+
typeAppStatusIconProps={
13+
status:WorkspaceAppStatus;
14+
latest:boolean;
15+
className?:string;
16+
};
17+
18+
exportconstAppStatusIcon:FC<AppStatusIconProps>=({
19+
status,
20+
latest,
21+
className:customClassName,
22+
})=>{
23+
constclassName=cn(["size-4 shrink-0",customClassName]);
24+
25+
switch(status.state){
26+
case"complete":
27+
return(
28+
<CircleCheckIconclassName={cn([className,"text-content-success"])}/>
29+
);
30+
case"failure":
31+
return(
32+
<CircleAlertIconclassName={cn([className,"text-content-warning"])}/>
33+
);
34+
case"working":
35+
returnlatest ?(
36+
<Spinnersize="sm"className="shrink-0"loading/>
37+
) :(
38+
<HourglassIconclassName={cn([className,"text-highlight-sky"])}/>
39+
);
40+
default:
41+
return(
42+
<TriangleAlertIcon
43+
className={cn([className,"text-content-secondary"])}
44+
/>
45+
);
46+
}
47+
};

‎site/src/modules/tasks/tasks.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
importtype{Workspace}from"api/typesGenerated";
2+
3+
exportconstAI_PROMPT_PARAMETER_NAME="AI Prompt";
4+
5+
exporttypeTask={
6+
workspace:Workspace;
7+
prompt:string;
8+
};

‎site/src/modules/workspaces/WorkspaceAppStatus/WorkspaceAppStatus.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const WorkspaceAppStatus = ({
3434
}
3535

3636
return(
37-
<divclassName="flex flex-col">
37+
<divclassName="flex flex-col text-content-secondary">
3838
<TooltipProvider>
3939
<Tooltip>
4040
<TooltipTriggerasChild>
@@ -48,7 +48,9 @@ export const WorkspaceAppStatus = ({
4848
<TooltipContent>{status.message}</TooltipContent>
4949
</Tooltip>
5050
</TooltipProvider>
51-
<spanclassName="first-letter:uppercase block pl-6">{status.state}</span>
51+
<spanclassName="text-xs first-letter:uppercase block pl-6">
52+
{status.state}
53+
</span>
5254
</div>
5355
);
5456
};
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{spyOn}from"@storybook/test";
3+
import{
4+
MockFailedWorkspace,
5+
MockStartingWorkspace,
6+
MockStoppedWorkspace,
7+
MockWorkspace,
8+
MockWorkspaceAgent,
9+
MockWorkspaceApp,
10+
MockWorkspaceAppStatus,
11+
MockWorkspaceResource,
12+
mockApiError,
13+
}from"testHelpers/entities";
14+
import{withProxyProvider}from"testHelpers/storybook";
15+
importTaskPage,{data}from"./TaskPage";
16+
17+
constmeta:Meta<typeofTaskPage>={
18+
title:"pages/TaskPage",
19+
component:TaskPage,
20+
parameters:{
21+
layout:"fullscreen",
22+
},
23+
};
24+
25+
exportdefaultmeta;
26+
typeStory=StoryObj<typeofTaskPage>;
27+
28+
exportconstLoading:Story={
29+
beforeEach:()=>{
30+
spyOn(data,"fetchTask").mockImplementation(
31+
()=>newPromise((res)=>1000*60*60),
32+
);
33+
},
34+
};
35+
36+
exportconstLoadingError:Story={
37+
beforeEach:()=>{
38+
spyOn(data,"fetchTask").mockRejectedValue(
39+
mockApiError({
40+
message:"Failed to load task",
41+
detail:"You don't have permission to access this resource.",
42+
}),
43+
);
44+
},
45+
};
46+
47+
exportconstWaitingOnBuild:Story={
48+
beforeEach:()=>{
49+
spyOn(data,"fetchTask").mockResolvedValue({
50+
prompt:"Create competitors page",
51+
workspace:MockStartingWorkspace,
52+
});
53+
},
54+
};
55+
56+
exportconstWaitingOnStatus:Story={
57+
beforeEach:()=>{
58+
spyOn(data,"fetchTask").mockResolvedValue({
59+
prompt:"Create competitors page",
60+
workspace:{
61+
...MockWorkspace,
62+
latest_app_status:null,
63+
},
64+
});
65+
},
66+
};
67+
68+
exportconstFailedBuild:Story={
69+
beforeEach:()=>{
70+
spyOn(data,"fetchTask").mockResolvedValue({
71+
prompt:"Create competitors page",
72+
workspace:MockFailedWorkspace,
73+
});
74+
},
75+
};
76+
77+
exportconstTerminatedBuild:Story={
78+
beforeEach:()=>{
79+
spyOn(data,"fetchTask").mockResolvedValue({
80+
prompt:"Create competitors page",
81+
workspace:MockStoppedWorkspace,
82+
});
83+
},
84+
};
85+
86+
exportconstTerminatedBuildWithStatus:Story={
87+
beforeEach:()=>{
88+
spyOn(data,"fetchTask").mockResolvedValue({
89+
prompt:"Create competitors page",
90+
workspace:{
91+
...MockStoppedWorkspace,
92+
latest_app_status:MockWorkspaceAppStatus,
93+
},
94+
});
95+
},
96+
};
97+
98+
exportconstActive:Story={
99+
decorators:[withProxyProvider()],
100+
beforeEach:()=>{
101+
spyOn(data,"fetchTask").mockResolvedValue({
102+
prompt:"Create competitors page",
103+
workspace:{
104+
...MockWorkspace,
105+
latest_build:{
106+
...MockWorkspace.latest_build,
107+
resources:[
108+
{
109+
...MockWorkspaceResource,
110+
agents:[
111+
{
112+
...MockWorkspaceAgent,
113+
apps:[
114+
{
115+
...MockWorkspaceApp,
116+
id:"claude-code",
117+
display_name:"Claude Code",
118+
icon:"/icon/claude.svg",
119+
url:`${window.location.protocol}/iframe.html?viewMode=story&id=pages-terminal--ready&args=&globals=`,
120+
external:true,
121+
statuses:[
122+
MockWorkspaceAppStatus,
123+
{
124+
...MockWorkspaceAppStatus,
125+
id:"2",
126+
message:"Planning changes",
127+
state:"working",
128+
},
129+
],
130+
},
131+
{
132+
...MockWorkspaceApp,
133+
id:"vscode",
134+
display_name:"VSCode",
135+
icon:"/icon/code.svg",
136+
},
137+
],
138+
},
139+
],
140+
},
141+
],
142+
},
143+
latest_app_status:{
144+
...MockWorkspaceAppStatus,
145+
app_id:"claude-code",
146+
},
147+
},
148+
});
149+
},
150+
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp