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

Commitf78b5c1

Browse files
chore(site): refactor logs and add stories (#12553)
1 parent0723dd3 commitf78b5c1

File tree

11 files changed

+278
-201
lines changed

11 files changed

+278
-201
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{chromatic}from"testHelpers/chromatic";
3+
import{LogLine,LogLinePrefix}from"./LogLine";
4+
5+
constmeta:Meta<typeofLogLine>={
6+
title:"components/Logs/LogLine",
7+
parameters:{ chromatic},
8+
component:LogLine,
9+
args:{
10+
level:"info",
11+
children:(
12+
<>
13+
<LogLinePrefix>13:45:31.072</LogLinePrefix>
14+
<span>info: Starting build</span>
15+
</>
16+
),
17+
},
18+
};
19+
20+
exportdefaultmeta;
21+
22+
typeStory=StoryObj<typeofLogLine>;
23+
24+
exportconstInfo:Story={};
25+
26+
exportconstDebug:Story={
27+
args:{
28+
level:"debug",
29+
},
30+
};
31+
32+
exportconstError:Story={
33+
args:{
34+
level:"error",
35+
},
36+
};
37+
38+
exportconstTrace:Story={
39+
args:{
40+
level:"trace",
41+
},
42+
};
43+
44+
exportconstWarn:Story={
45+
args:{
46+
level:"warn",
47+
},
48+
};

‎site/src/components/Logs/LogLine.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
importtype{Interpolation,Theme}from"@emotion/react";
2+
importtype{FC,HTMLAttributes}from"react";
3+
importtype{LogLevel}from"api/typesGenerated";
4+
import{MONOSPACE_FONT_FAMILY}from"theme/constants";
5+
6+
exportconstDEFAULT_LOG_LINE_SIDE_PADDING=24;
7+
8+
exportinterfaceLine{
9+
time:string;
10+
output:string;
11+
level:LogLevel;
12+
sourceId:string;
13+
}
14+
15+
typeLogLineProps={
16+
level:LogLevel;
17+
}&HTMLAttributes<HTMLPreElement>;
18+
19+
exportconstLogLine:FC<LogLineProps>=({ level, ...divProps})=>{
20+
return(
21+
<pre
22+
css={styles.line}
23+
className={`${level}${divProps.className} logs-line`}
24+
{...divProps}
25+
/>
26+
);
27+
};
28+
29+
exportconstLogLinePrefix:FC<HTMLAttributes<HTMLSpanElement>>=(props)=>{
30+
return<precss={styles.prefix}{...props}/>;
31+
};
32+
33+
conststyles={
34+
line:(theme)=>({
35+
margin:0,
36+
wordBreak:"break-all",
37+
display:"flex",
38+
alignItems:"center",
39+
fontSize:13,
40+
color:theme.palette.text.primary,
41+
fontFamily:MONOSPACE_FONT_FAMILY,
42+
height:"auto",
43+
padding:`0 var(--log-line-side-padding,${DEFAULT_LOG_LINE_SIDE_PADDING}px)`,
44+
45+
"&.error":{
46+
backgroundColor:theme.roles.error.background,
47+
color:theme.roles.error.text,
48+
49+
"& .dashed-line":{
50+
backgroundColor:theme.roles.error.outline,
51+
},
52+
},
53+
54+
"&.debug":{
55+
backgroundColor:theme.roles.info.background,
56+
color:theme.roles.info.text,
57+
58+
"& .dashed-line":{
59+
backgroundColor:theme.roles.info.outline,
60+
},
61+
},
62+
63+
"&.warn":{
64+
backgroundColor:theme.roles.warning.background,
65+
color:theme.roles.warning.text,
66+
67+
"& .dashed-line":{
68+
backgroundColor:theme.roles.warning.outline,
69+
},
70+
},
71+
}),
72+
73+
prefix:(theme)=>({
74+
userSelect:"none",
75+
margin:0,
76+
display:"inline-block",
77+
color:theme.palette.text.secondary,
78+
marginRight:24,
79+
}),
80+
}satisfiesRecord<string,Interpolation<Theme>>;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{chromatic}from"testHelpers/chromatic";
3+
import{MockWorkspaceBuildLogs}from"testHelpers/entities";
4+
import{Logs}from"./Logs";
5+
6+
constmeta:Meta<typeofLogs>={
7+
title:"components/Logs",
8+
parameters:{ chromatic},
9+
component:Logs,
10+
args:{
11+
lines:MockWorkspaceBuildLogs.map((log)=>({
12+
level:log.log_level,
13+
time:log.created_at,
14+
output:log.output,
15+
sourceId:log.log_source,
16+
})),
17+
},
18+
};
19+
20+
exportdefaultmeta;
21+
22+
typeStory=StoryObj<typeofLogs>;
23+
24+
constDefault:Story={};
25+
26+
export{DefaultasLogs};

‎site/src/components/Logs/Logs.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
importtype{Interpolation,Theme}from"@emotion/react";
2+
importdayjsfrom"dayjs";
3+
importtype{FC}from"react";
4+
import{LogLinePrefix,LogLine,typeLine}from"./LogLine";
5+
6+
exportconstDEFAULT_LOG_LINE_SIDE_PADDING=24;
7+
8+
exportinterfaceLogsProps{
9+
lines:Line[];
10+
hideTimestamps?:boolean;
11+
className?:string;
12+
}
13+
14+
exportconstLogs:FC<LogsProps>=({
15+
hideTimestamps,
16+
lines,
17+
className="",
18+
})=>{
19+
return(
20+
<divcss={styles.root}className={`${className} logs-container`}>
21+
<divcss={{minWidth:"fit-content"}}>
22+
{lines.map((line,idx)=>(
23+
<LogLinekey={idx}level={line.level}>
24+
{!hideTimestamps&&(
25+
<LogLinePrefix>
26+
{dayjs(line.time).format(`HH:mm:ss.SSS`)}
27+
</LogLinePrefix>
28+
)}
29+
<span>{line.output}</span>
30+
</LogLine>
31+
))}
32+
</div>
33+
</div>
34+
);
35+
};
36+
37+
conststyles={
38+
root:(theme)=>({
39+
minHeight:156,
40+
padding:"8px 0",
41+
borderRadius:8,
42+
overflowX:"auto",
43+
background:theme.palette.background.default,
44+
45+
"&:not(:last-child)":{
46+
borderBottom:`1px solid${theme.palette.divider}`,
47+
borderRadius:0,
48+
},
49+
}),
50+
}satisfiesRecord<string,Interpolation<Theme>>;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
importtype{Interpolation,Theme}from"@emotion/react";
2+
importAnsiToHTMLfrom"ansi-to-html";
3+
import{typeFC,typeReactNode,useMemo}from"react";
4+
import{typeLine,LogLine,LogLinePrefix}from"components/Logs/LogLine";
5+
6+
constconvert=newAnsiToHTML();
7+
8+
interfaceAgentLogLineProps{
9+
line:Line;
10+
number:number;
11+
style:React.CSSProperties;
12+
sourceIcon:ReactNode;
13+
maxLineNumber:number;
14+
}
15+
16+
exportconstAgentLogLine:FC<AgentLogLineProps>=({
17+
line,
18+
number,
19+
maxLineNumber,
20+
sourceIcon,
21+
style,
22+
})=>{
23+
constoutput=useMemo(()=>{
24+
returnconvert.toHtml(line.output.split(/\r/g).pop()asstring);
25+
},[line.output]);
26+
27+
return(
28+
<LogLinecss={{paddingLeft:16}}level={line.level}style={style}>
29+
{sourceIcon}
30+
<LogLinePrefix
31+
css={styles.number}
32+
style={{
33+
minWidth:`${maxLineNumber.toString().length-1}em`,
34+
}}
35+
>
36+
{number}
37+
</LogLinePrefix>
38+
<span
39+
// Output contains HTML to represent ANSI-code formatting
40+
dangerouslySetInnerHTML={{
41+
__html:output,
42+
}}
43+
/>
44+
</LogLine>
45+
);
46+
};
47+
48+
conststyles={
49+
number:(theme)=>({
50+
width:32,
51+
textAlign:"right",
52+
flexShrink:0,
53+
color:theme.palette.text.disabled,
54+
}),
55+
}satisfiesRecord<string,Interpolation<Theme>>;

‎site/src/modules/resources/AgentLogs.tsx

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@ import {
1010
import{FixedSizeListasList}from"react-window";
1111
import*asAPIfrom"api/api";
1212
importtype{WorkspaceAgentLogSource}from"api/typesGenerated";
13-
import{
14-
LogLine,
15-
logLineHeight,
16-
}from"modules/workspaces/WorkspaceBuildLogs/Logs";
17-
importtype{LineWithID}from"./AgentRow";
13+
import{AgentLogLine}from"./AgentLogLine";
14+
import{AGENT_LOG_LINE_HEIGHT,typeLineWithID}from"./AgentRow";
1815

1916
typeAgentLogsProps=Omit<
2017
ComponentProps<typeofList>,
@@ -39,7 +36,7 @@ export const AgentLogs = forwardRef<List, AgentLogsProps>(
3936
ref={ref}
4037
css={styles.logs}
4138
itemCount={logs.length}
42-
itemSize={logLineHeight}
39+
itemSize={AGENT_LOG_LINE_HEIGHT}
4340
{...listProps}
4441
>
4542
{({ index, style})=>{
@@ -58,7 +55,7 @@ export const AgentLogs = forwardRef<List, AgentLogsProps>(
5855
}
5956
);
6057
};
61-
constlogSource=getLogSource(log.source_id);
58+
constlogSource=getLogSource(log.sourceId);
6259

6360
letassignedIcon=false;
6461
leticon:JSX.Element;
@@ -98,7 +95,7 @@ export const AgentLogs = forwardRef<List, AgentLogsProps>(
9895
letnextChangesSource=false;
9996
if(index<logs.length-1){
10097
nextChangesSource=
101-
getLogSource(logs[index+1].source_id).id!==log.source_id;
98+
getLogSource(logs[index+1].sourceId).id!==log.sourceId;
10299
}
103100
// We don't want every line to repeat the icon, because
104101
// that is ugly and repetitive. This removes the icon
@@ -107,7 +104,7 @@ export const AgentLogs = forwardRef<List, AgentLogsProps>(
107104
// same source.
108105
if(
109106
index>0&&
110-
getLogSource(logs[index-1].source_id).id===log.source_id
107+
getLogSource(logs[index-1].sourceId).id===log.sourceId
111108
){
112109
icon=(
113110
<div
@@ -149,10 +146,10 @@ export const AgentLogs = forwardRef<List, AgentLogsProps>(
149146
}
150147

151148
return(
152-
<LogLine
149+
<AgentLogLine
153150
line={logs[index]}
154151
number={index+1}
155-
maxNumber={logs.length}
152+
maxLineNumber={logs.length}
156153
style={style}
157154
sourceIcon={
158155
<Tooltip
@@ -208,7 +205,7 @@ export const useAgentLogs = (
208205
level:log.level||"info",
209206
output:log.output,
210207
time:log.created_at,
211-
source_id:log.source_id,
208+
sourceId:log.source_id,
212209
}));
213210

214211
if(!previousLogs){

‎site/src/modules/resources/AgentRow.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const storybookLogs: LineWithID[] = [
7979
level:"info",
8080
output:line,
8181
time:"",
82-
source_id:M.MockWorkspaceAgentLogSource.id,
82+
sourceId:M.MockWorkspaceAgentLogSource.id,
8383
}));
8484

8585
constmeta:Meta<typeofAgentRow>={

‎site/src/modules/resources/AgentRow.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@ import type {
2121
WorkspaceAgentMetadata,
2222
}from"api/typesGenerated";
2323
import{DropdownArrow}from"components/DropdownArrow/DropdownArrow";
24+
importtype{Line}from"components/Logs/LogLine";
2425
import{Stack}from"components/Stack/Stack";
2526
import{useProxy}from"contexts/ProxyContext";
26-
import{
27-
typeLine,
28-
logLineHeight,
29-
}from"modules/workspaces/WorkspaceBuildLogs/Logs";
3027
import{AgentLatency}from"./AgentLatency";
3128
import{AgentLogs,useAgentLogs}from"./AgentLogs";
3229
import{AgentMetadata}from"./AgentMetadata";
@@ -39,6 +36,9 @@ import { TerminalLink } from "./TerminalLink/TerminalLink";
3936
import{VSCodeDesktopButton}from"./VSCodeDesktopButton/VSCodeDesktopButton";
4037
import{XRayScanAlert}from"./XRayScanAlert";
4138

39+
// Approximate height of a log line. Used to control virtualized list height.
40+
exportconstAGENT_LOG_LINE_HEIGHT=20;
41+
4242
// Logs are stored as the Line interface to make rendering
4343
// much more efficient. Instead of mapping objects each time, we're
4444
// able to just pass the array of logs to the component.
@@ -115,7 +115,7 @@ export const AgentRow: FC<AgentRowProps> = ({
115115
level:"error",
116116
output:"Startup logs exceeded the max size of 1MB!",
117117
time:newDate().toISOString(),
118-
source_id:"",
118+
sourceId:"",
119119
});
120120
}
121121
returnlogs;
@@ -154,7 +154,7 @@ export const AgentRow: FC<AgentRowProps> = ({
154154
constdistanceFromBottom=
155155
logListDivRef.current.scrollHeight-
156156
(props.scrollOffset+parent.clientHeight);
157-
setBottomOfLogs(distanceFromBottom<logLineHeight);
157+
setBottomOfLogs(distanceFromBottom<AGENT_LOG_LINE_HEIGHT);
158158
},
159159
[logListDivRef],
160160
);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp