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

Commit4732f08

Browse files
authored
fix: show an error when a user doesn't have permission to view the health page (#16580)
1 parent2c6df5a commit4732f08

File tree

1 file changed

+149
-134
lines changed

1 file changed

+149
-134
lines changed

‎site/src/pages/HealthPage/HealthLayout.tsx

Lines changed: 149 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import IconButton from "@mui/material/IconButton";
77
importTooltipfrom"@mui/material/Tooltip";
88
import{health,refreshHealth}from"api/queries/debug";
99
importtype{HealthSeverity}from"api/typesGenerated";
10+
import{ErrorAlert}from"components/Alert/ErrorAlert";
1011
import{Loader}from"components/Loader/Loader";
1112
import{typeClassName,useClassName}from"hooks/useClassName";
1213
importkebabCasefrom"lodash/fp/kebabCase";
@@ -22,7 +23,11 @@ import { HealthIcon } from "./Content";
2223
exportconstHealthLayout:FC=()=>{
2324
consttheme=useTheme();
2425
constqueryClient=useQueryClient();
25-
const{data:healthStatus}=useQuery({
26+
const{
27+
data:healthStatus,
28+
isLoading,
29+
error,
30+
}=useQuery({
2631
...health(),
2732
refetchInterval:30_000,
2833
});
@@ -42,161 +47,171 @@ export const HealthLayout: FC = () => {
4247
constlink=useClassName(classNames.link,[]);
4348
constactiveLink=useClassName(classNames.activeLink,[]);
4449

50+
if(isLoading||!healthStatus){
51+
return(
52+
<divclassName="p-6">
53+
<Loader/>
54+
</div>
55+
);
56+
}
57+
58+
if(error){
59+
return(
60+
<divclassName="p-6">
61+
<ErrorAlerterror={error}/>
62+
</div>
63+
);
64+
}
65+
4566
return(
4667
<>
4768
<Helmet>
4869
<title>{pageTitle("Health")}</title>
4970
</Helmet>
5071

51-
{healthStatus ?(
52-
<DashboardFullPage>
72+
<DashboardFullPage>
73+
<div
74+
css={{
75+
display:"flex",
76+
flexBasis:0,
77+
flex:1,
78+
overflow:"hidden",
79+
}}
80+
>
5381
<div
5482
css={{
55-
display:"flex",
56-
flexBasis:0,
57-
flex:1,
58-
overflow:"hidden",
83+
width:256,
84+
flexShrink:0,
85+
borderRight:`1px solid${theme.palette.divider}`,
86+
fontSize:14,
5987
}}
6088
>
6189
<div
6290
css={{
63-
width:256,
64-
flexShrink:0,
65-
borderRight:`1px solid${theme.palette.divider}`,
66-
fontSize:14,
91+
padding:24,
92+
display:"flex",
93+
flexDirection:"column",
94+
gap:16,
6795
}}
6896
>
69-
<div
70-
css={{
71-
padding:24,
72-
display:"flex",
73-
flexDirection:"column",
74-
gap:16,
75-
}}
76-
>
77-
<div>
78-
<div
79-
css={{
80-
display:"flex",
81-
alignItems:"center",
82-
justifyContent:"space-between",
83-
}}
84-
>
85-
<HealthIconsize={32}severity={healthStatus.severity}/>
86-
87-
<Tooltiptitle="Refresh health checks">
88-
<IconButton
89-
size="small"
90-
disabled={isRefreshing}
91-
data-testid="healthcheck-refresh-button"
92-
onClick={()=>{
93-
forceRefresh();
94-
}}
95-
>
96-
{isRefreshing ?(
97-
<CircularProgresssize={16}/>
98-
) :(
99-
<ReplayIconcss={{width:20,height:20}}/>
100-
)}
101-
</IconButton>
102-
</Tooltip>
103-
</div>
104-
<divcss={{fontWeight:500,marginTop:16}}>
105-
{healthStatus.healthy ?"Healthy" :"Unhealthy"}
106-
</div>
107-
<div
108-
css={{
109-
color:theme.palette.text.secondary,
110-
lineHeight:"150%",
111-
}}
112-
>
113-
{healthStatus.healthy
114-
?Object.keys(visibleSections).some((key)=>{
115-
constsection=
116-
healthStatus[keyaskeyoftypeofvisibleSections];
117-
return(
118-
section.warnings&&section.warnings.length>0
119-
);
120-
})
121-
?"All systems operational, but performance might be degraded"
122-
:"All systems operational"
123-
:"Some issues have been detected"}
124-
</div>
125-
</div>
97+
<div>
98+
<div
99+
css={{
100+
display:"flex",
101+
alignItems:"center",
102+
justifyContent:"space-between",
103+
}}
104+
>
105+
<HealthIconsize={32}severity={healthStatus.severity}/>
126106

127-
<divcss={{display:"flex",flexDirection:"column"}}>
128-
<spancss={{fontWeight:500}}>Last check</span>
129-
<span
130-
data-chromatic="ignore"
131-
css={{
132-
color:theme.palette.text.secondary,
133-
lineHeight:"150%",
134-
}}
135-
>
136-
{createDayString(healthStatus.time)}
137-
</span>
107+
<Tooltiptitle="Refresh health checks">
108+
<IconButton
109+
size="small"
110+
disabled={isRefreshing}
111+
data-testid="healthcheck-refresh-button"
112+
onClick={()=>{
113+
forceRefresh();
114+
}}
115+
>
116+
{isRefreshing ?(
117+
<CircularProgresssize={16}/>
118+
) :(
119+
<ReplayIconcss={{width:20,height:20}}/>
120+
)}
121+
</IconButton>
122+
</Tooltip>
138123
</div>
139-
140-
<divcss={{display:"flex",flexDirection:"column"}}>
141-
<spancss={{fontWeight:500}}>Version</span>
142-
<span
143-
data-chromatic="ignore"
144-
css={{
145-
color:theme.palette.text.secondary,
146-
lineHeight:"150%",
147-
}}
148-
>
149-
{healthStatus.coder_version}
150-
</span>
124+
<divcss={{fontWeight:500,marginTop:16}}>
125+
{healthStatus.healthy ?"Healthy" :"Unhealthy"}
126+
</div>
127+
<div
128+
css={{
129+
color:theme.palette.text.secondary,
130+
lineHeight:"150%",
131+
}}
132+
>
133+
{healthStatus.healthy
134+
?Object.keys(visibleSections).some((key)=>{
135+
constsection=
136+
healthStatus[keyaskeyoftypeofvisibleSections];
137+
returnsection.warnings&&section.warnings.length>0;
138+
})
139+
?"All systems operational, but performance might be degraded"
140+
:"All systems operational"
141+
:"Some issues have been detected"}
151142
</div>
152143
</div>
153144

154-
<navcss={{display:"flex",flexDirection:"column",gap:1}}>
155-
{Object.entries(visibleSections)
156-
.sort()
157-
.map(([key,label])=>{
158-
consthealthSection=
159-
healthStatus[keyaskeyoftypeofvisibleSections];
160-
161-
return(
162-
<NavLink
163-
end
164-
key={key}
165-
to={`/health/${kebabCase(key)}`}
166-
className={({ isActive})=>
167-
cx([link,isActive&&activeLink])
168-
}
169-
>
170-
<HealthIcon
171-
size={16}
172-
severity={healthSection.severityasHealthSeverity}
173-
/>
174-
{label}
175-
{healthSection.dismissed&&(
176-
<NotificationsOffOutlined
177-
css={{
178-
fontSize:14,
179-
marginLeft:"auto",
180-
color:theme.palette.text.disabled,
181-
}}
182-
/>
183-
)}
184-
</NavLink>
185-
);
186-
})}
187-
</nav>
188-
</div>
145+
<divcss={{display:"flex",flexDirection:"column"}}>
146+
<spancss={{fontWeight:500}}>Last check</span>
147+
<span
148+
data-chromatic="ignore"
149+
css={{
150+
color:theme.palette.text.secondary,
151+
lineHeight:"150%",
152+
}}
153+
>
154+
{createDayString(healthStatus.time)}
155+
</span>
156+
</div>
189157

190-
<divcss={{overflowY:"auto",width:"100%"}}>
191-
<Suspensefallback={<Loader/>}>
192-
<Outletcontext={healthStatus}/>
193-
</Suspense>
158+
<divcss={{display:"flex",flexDirection:"column"}}>
159+
<spancss={{fontWeight:500}}>Version</span>
160+
<span
161+
data-chromatic="ignore"
162+
css={{
163+
color:theme.palette.text.secondary,
164+
lineHeight:"150%",
165+
}}
166+
>
167+
{healthStatus.coder_version}
168+
</span>
169+
</div>
194170
</div>
171+
172+
<navcss={{display:"flex",flexDirection:"column",gap:1}}>
173+
{Object.entries(visibleSections)
174+
.sort()
175+
.map(([key,label])=>{
176+
consthealthSection=
177+
healthStatus[keyaskeyoftypeofvisibleSections];
178+
179+
return(
180+
<NavLink
181+
end
182+
key={key}
183+
to={`/health/${kebabCase(key)}`}
184+
className={({ isActive})=>
185+
cx([link,isActive&&activeLink])
186+
}
187+
>
188+
<HealthIcon
189+
size={16}
190+
severity={healthSection.severityasHealthSeverity}
191+
/>
192+
{label}
193+
{healthSection.dismissed&&(
194+
<NotificationsOffOutlined
195+
css={{
196+
fontSize:14,
197+
marginLeft:"auto",
198+
color:theme.palette.text.disabled,
199+
}}
200+
/>
201+
)}
202+
</NavLink>
203+
);
204+
})}
205+
</nav>
195206
</div>
196-
</DashboardFullPage>
197-
) :(
198-
<Loader/>
199-
)}
207+
208+
<divcss={{overflowY:"auto",width:"100%"}}>
209+
<Suspensefallback={<Loader/>}>
210+
<Outletcontext={healthStatus}/>
211+
</Suspense>
212+
</div>
213+
</div>
214+
</DashboardFullPage>
200215
</>
201216
);
202217
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp