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

Commitb4daf36

Browse files
refactor: refactor activity column in the workspaces table (#17976)
The goal is to better integrate the activity column data with theexistent data:- Make the message one line, the full message is in the tooltip, anddisplay the state at the bottom. This way, it is visually consistentwith the other columns like status, name and template.- Moved the app, and uri, to the actions column, instead of showing themtogether with the message in the activity column.**Previous:**<img width="1512" alt="Screenshot 2025-05-21 at 17 28 46"src="https://github.com/user-attachments/assets/ea9188a5-d82e-416c-b961-edf0104f66c6"/>**After:**<img width="1512" alt="Screenshot 2025-05-21 at 17 28 57"src="https://github.com/user-attachments/assets/f50dbe82-cd3e-4448-9fa2-bde9193166d6"/>
1 parentc777740 commitb4daf36

File tree

3 files changed

+107
-341
lines changed

3 files changed

+107
-341
lines changed

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

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import type { Meta, StoryObj } from "@storybook/react";
22
import{ProxyContext,getPreferredProxy}from"contexts/ProxyContext";
33
import{
44
MockProxyLatencies,
5-
MockWorkspace,
6-
MockWorkspaceAgent,
7-
MockWorkspaceApp,
85
MockWorkspaceAppStatus,
96
}from"testHelpers/entities";
107
import{WorkspaceAppStatus}from"./WorkspaceAppStatus";
@@ -68,24 +65,6 @@ export const Working: Story = {
6865
},
6966
};
7067

71-
exportconstLongURI:Story={
72-
args:{
73-
status:{
74-
...MockWorkspaceAppStatus,
75-
uri:"https://www.google.com/search?q=hello+world+plus+a+lot+of+other+words",
76-
},
77-
},
78-
};
79-
80-
exportconstFileURI:Story={
81-
args:{
82-
status:{
83-
...MockWorkspaceAppStatus,
84-
uri:"file:///Users/jason/Desktop/test.txt",
85-
},
86-
},
87-
};
88-
8968
exportconstLongMessage:Story={
9069
args:{
9170
status:{
@@ -95,14 +74,3 @@ export const LongMessage: Story = {
9574
},
9675
},
9776
};
98-
99-
exportconstWithApp:Story={
100-
args:{
101-
status:MockWorkspaceAppStatus,
102-
app:{
103-
...MockWorkspaceApp,
104-
},
105-
agent:MockWorkspaceAgent,
106-
workspace:MockWorkspace,
107-
},
108-
};
Lines changed: 34 additions & 285 deletions
Original file line numberDiff line numberDiff line change
@@ -1,305 +1,54 @@
1-
importtype{Theme}from"@emotion/react";
2-
import{useTheme}from"@emotion/react";
3-
importCircularProgressfrom"@mui/material/CircularProgress";
41
importtype{
52
WorkspaceAppStatusasAPIWorkspaceAppStatus,
6-
Workspace,
7-
WorkspaceAgent,
8-
WorkspaceApp,
3+
WorkspaceAppStatusState,
94
}from"api/typesGenerated";
5+
import{Spinner}from"components/Spinner/Spinner";
106
import{
11-
CircleAlertIcon,
12-
CircleCheckIcon,
13-
ExternalLinkIcon,
14-
FileIcon,
15-
LayoutGridIcon,
16-
TriangleAlertIcon,
17-
}from"lucide-react";
18-
import{useAppLink}from"modules/apps/useAppLink";
19-
importtype{FC}from"react";
20-
21-
constformatURI=(uri:string)=>{
22-
try{
23-
consturl=newURL(uri);
24-
returnurl.hostname+url.pathname;
25-
}catch{
26-
returnuri;
27-
}
28-
};
29-
30-
constgetStatusColor=(
31-
theme:Theme,
32-
state:APIWorkspaceAppStatus["state"],
33-
)=>{
34-
switch(state){
35-
case"complete":
36-
returntheme.palette.success.main;
37-
case"failure":
38-
returntheme.palette.error.main;
39-
case"working":
40-
returntheme.palette.primary.main;
41-
default:
42-
// Assuming unknown state maps to warning/secondary visually
43-
returntheme.palette.text.secondary;
44-
}
45-
};
46-
47-
constgetStatusIcon=(theme:Theme,state:APIWorkspaceAppStatus["state"])=>{
48-
constcolor=getStatusColor(theme,state);
49-
switch(state){
50-
case"complete":
51-
return<CircleCheckIconclassName="size-icon-xs"style={{ color}}/>;
52-
case"failure":
53-
return<CircleAlertIconclassName="size-icon-xs"style={{ color}}/>;
54-
case"working":
55-
return<CircularProgresssize={16}sx={{ color}}/>;
56-
default:
57-
return<TriangleAlertIconclassName="size-icon-xs"style={{ color}}/>;
58-
}
7+
Tooltip,
8+
TooltipContent,
9+
TooltipProvider,
10+
TooltipTrigger,
11+
}from"components/Tooltip/Tooltip";
12+
import{CircleAlertIcon,CircleCheckIcon}from"lucide-react";
13+
importtype{ReactNode}from"react";
14+
15+
consticonByState:Record<WorkspaceAppStatusState,ReactNode>={
16+
complete:(
17+
<CircleCheckIconclassName="size-4 shrink-0 text-content-success"/>
18+
),
19+
failure:<CircleAlertIconclassName="size-4 shrink-0 text-content-warning"/>,
20+
working:<Spinnersize="sm"className="shrink-0"loading/>,
5921
};
6022

6123
exportconstWorkspaceAppStatus=({
62-
workspace,
6324
status,
64-
agent,
65-
app,
6625
}:{
67-
workspace:Workspace;
68-
status?:APIWorkspaceAppStatus|null;
69-
app?:WorkspaceApp;
70-
agent?:WorkspaceAgent;
26+
status:APIWorkspaceAppStatus|null;
7127
})=>{
72-
consttheme=useTheme();
73-
constcommonStyles=useCommonStyles();
74-
7528
if(!status){
7629
return(
77-
<div
78-
css={{
79-
display:"flex",
80-
alignItems:"center",
81-
gap:12,
82-
minWidth:0,
83-
paddingRight:16,
84-
}}
85-
>
86-
<div
87-
css={{
88-
fontSize:"14px",
89-
color:theme.palette.text.disabled,
90-
flexShrink:1,
91-
minWidth:0,
92-
}}
93-
>
94-
95-
</div>
96-
</div>
30+
<spanclassName="text-content-disabled text-sm">
31+
-<spanclassName="sr-only">No activity</span>
32+
</span>
9733
);
9834
}
99-
constisFileURI=status.uri?.startsWith("file://");
10035

10136
return(
102-
<div
103-
css={{
104-
display:"flex",
105-
alignItems:"flex-start",
106-
gap:8,
107-
minWidth:0,
108-
paddingRight:16,
109-
}}
110-
>
111-
<div
112-
css={{
113-
display:"flex",
114-
alignItems:"center",
115-
flexShrink:0,
116-
marginTop:2,
117-
}}
118-
>
119-
{getStatusIcon(theme,status.state)}
120-
</div>
121-
<div
122-
css={{
123-
display:"flex",
124-
flexDirection:"column",
125-
gap:6,
126-
minWidth:0,
127-
flex:1,
128-
}}
129-
>
130-
<div
131-
css={{
132-
fontSize:"14px",
133-
lineHeight:"20px",
134-
color:"text.primary",
135-
margin:0,
136-
display:"-webkit-box",
137-
WebkitLineClamp:2,
138-
WebkitBoxOrient:"vertical",
139-
overflow:"hidden",
140-
textOverflow:"ellipsis",
141-
maxWidth:"100%",
142-
}}
143-
>
144-
{status.message}
145-
</div>
146-
<div
147-
css={{
148-
display:"flex",
149-
alignItems:"center",
150-
}}
151-
>
152-
{app&&agent&&(
153-
<AppLinkapp={app}workspace={workspace}agent={agent}/>
154-
)}
155-
{status.uri&&(
156-
<div
157-
css={{
158-
display:"flex",
159-
minWidth:0,
160-
}}
161-
>
162-
{isFileURI ?(
163-
<div
164-
css={{
165-
...commonStyles,
166-
}}
167-
>
168-
<FileIcon
169-
className="size-icon-xs"
170-
css={{
171-
opacity:0.5,
172-
marginRight:"0.25rem",
173-
}}
174-
/>
175-
<span>{formatURI(status.uri)}</span>
176-
</div>
177-
) :(
178-
<a
179-
href={status.uri}
180-
target="_blank"
181-
rel="noopener noreferrer"
182-
css={{
183-
...commonStyles,
184-
color:theme.palette.text.secondary,
185-
"&:hover":{
186-
...commonStyles["&:hover"],
187-
color:theme.palette.text.primary,
188-
},
189-
}}
190-
>
191-
<ExternalLinkIcon
192-
className="size-icon-xs"
193-
css={{
194-
opacity:0.7,
195-
flexShrink:0,
196-
marginRight:2,
197-
}}
198-
/>
199-
<span
200-
css={{
201-
backgroundColor:"transparent",
202-
padding:0,
203-
color:"inherit",
204-
fontSize:"inherit",
205-
lineHeight:"inherit",
206-
overflow:"hidden",
207-
textOverflow:"ellipsis",
208-
whiteSpace:"nowrap",
209-
}}
210-
>
211-
{formatURI(status.uri)}
212-
</span>
213-
</a>
214-
)}
37+
<divclassName="flex flex-col">
38+
<TooltipProvider>
39+
<Tooltip>
40+
<TooltipTriggerasChild>
41+
<divclassName="flex items-center gap-2">
42+
{iconByState[status.state]}
43+
<spanclassName="whitespace-nowrap max-w-72 overflow-hidden text-ellipsis text-sm text-content-primary font-medium">
44+
{status.message}
45+
</span>
21546
</div>
216-
)}
217-
</div>
218-
</div>
47+
</TooltipTrigger>
48+
<TooltipContent>{status.message}</TooltipContent>
49+
</Tooltip>
50+
</TooltipProvider>
51+
<spanclassName="first-letter:uppercase block pl-6">{status.state}</span>
21952
</div>
22053
);
22154
};
222-
223-
typeAppLinkProps={
224-
app:WorkspaceApp;
225-
workspace:Workspace;
226-
agent:WorkspaceAgent;
227-
};
228-
229-
constAppLink:FC<AppLinkProps>=({ app, workspace, agent})=>{
230-
consttheme=useTheme();
231-
constcommonStyles=useCommonStyles();
232-
constlink=useAppLink(app,{ agent, workspace});
233-
234-
return(
235-
<a
236-
href={link.href}
237-
onClick={link.onClick}
238-
target="_blank"
239-
rel="noopener noreferrer"
240-
css={{
241-
...commonStyles,
242-
marginRight:8,
243-
position:"relative",
244-
color:theme.palette.text.secondary,
245-
"&:hover":{
246-
...commonStyles["&:hover"],
247-
color:theme.palette.text.primary,
248-
"& img":{
249-
opacity:1,
250-
},
251-
},
252-
}}
253-
>
254-
{app.icon ?(
255-
<img
256-
src={app.icon}
257-
alt={`${app.display_name} icon`}
258-
width={14}
259-
height={14}
260-
css={{
261-
borderRadius:"3px",
262-
opacity:0.8,
263-
marginRight:4,
264-
}}
265-
/>
266-
) :(
267-
<LayoutGridIcon
268-
className="size-icon-xs"
269-
css={{
270-
opacity:0.7,
271-
}}
272-
/>
273-
)}
274-
<span>{app.display_name}</span>
275-
</a>
276-
);
277-
};
278-
279-
constuseCommonStyles=()=>{
280-
consttheme=useTheme();
281-
282-
return{
283-
fontSize:"12px",
284-
lineHeight:"15px",
285-
color:theme.palette.text.disabled,
286-
display:"inline-flex",
287-
alignItems:"center",
288-
gap:4,
289-
padding:"2px 6px",
290-
borderRadius:"6px",
291-
bgcolor:"transparent",
292-
minWidth:0,
293-
maxWidth:"fit-content",
294-
overflow:"hidden",
295-
textOverflow:"ellipsis",
296-
whiteSpace:"nowrap",
297-
textDecoration:"none",
298-
transition:"all 0.15s ease-in-out",
299-
"&:hover":{
300-
textDecoration:"none",
301-
backgroundColor:theme.palette.action.hover,
302-
color:theme.palette.text.secondary,
303-
},
304-
};
305-
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp