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

Commit83c35bb

Browse files
authored
feat: display specific errors if templates page fails (#4023)
* Surface templates page errors* Format* Separate error messages* Fix story* Format* Format* Fix imports* Remove unnecessary check* Format
1 parent21e8fb2 commit83c35bb

File tree

8 files changed

+217
-175
lines changed

8 files changed

+217
-175
lines changed

‎site/src/AppRouter.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { NotFoundPage } from "./pages/404Page/404Page"
1616
import{CliAuthenticationPage}from"./pages/CliAuthPage/CliAuthPage"
1717
import{HealthzPage}from"./pages/HealthzPage/HealthzPage"
1818
import{LoginPage}from"./pages/LoginPage/LoginPage"
19-
importTemplatesPagefrom"./pages/TemplatesPage/TemplatesPage"
19+
import{TemplatesPage}from"./pages/TemplatesPage/TemplatesPage"
2020
import{AccountPage}from"./pages/UserSettingsPage/AccountPage/AccountPage"
2121
import{SecurityPage}from"./pages/UserSettingsPage/SecurityPage/SecurityPage"
2222
import{SSHKeysPage}from"./pages/UserSettingsPage/SSHKeysPage/SSHKeysPage"

‎site/src/i18n/en/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
importauditLogfrom"./auditLog.json"
22
importcommonfrom"./common.json"
33
importtemplatePagefrom"./templatePage.json"
4+
importtemplatesPagefrom"./templatesPage.json"
45
importworkspacePagefrom"./workspacePage.json"
56

67
exportconsten={
78
common,
89
workspacePage,
910
auditLog,
1011
templatePage,
12+
templatesPage,
1113
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"errors": {
3+
"getOrganizationError":"Something went wrong fetching organizations.",
4+
"getTemplatesError":"Something went wrong fetching templates."
5+
}
6+
}

‎site/src/pages/TemplatesPage/TemplatesPage.test.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as CreateDayString from "util/createDayString"
44
import{MockTemplate}from"../../testHelpers/entities"
55
import{history,render}from"../../testHelpers/renderHelpers"
66
import{server}from"../../testHelpers/server"
7-
importTemplatesPagefrom"./TemplatesPage"
7+
import{TemplatesPage}from"./TemplatesPage"
88
import{Language}from"./TemplatesPageView"
99

1010
describe("TemplatesPage",()=>{

‎site/src/pages/TemplatesPage/TemplatesPage.tsx‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,24 @@ import { XServiceContext } from "../../xServices/StateContext"
66
import{templatesMachine}from"../../xServices/templates/templatesXService"
77
import{TemplatesPageView}from"./TemplatesPageView"
88

9-
constTemplatesPage:React.FC=()=>{
9+
exportconstTemplatesPage:React.FC=()=>{
1010
constxServices=useContext(XServiceContext)
1111
const[authState]=useActor(xServices.authXService)
1212
const[templatesState]=useMachine(templatesMachine)
13+
const{ templates, getOrganizationsError, getTemplatesError}=templatesState.context
1314

1415
return(
1516
<>
1617
<Helmet>
1718
<title>{pageTitle("Templates")}</title>
1819
</Helmet>
1920
<TemplatesPageView
20-
templates={templatesState.context.templates}
21+
templates={templates}
2122
canCreateTemplate={authState.context.permissions?.createTemplates}
2223
loading={templatesState.hasTag("loading")}
24+
getOrganizationsError={getOrganizationsError}
25+
getTemplatesError={getTemplatesError}
2326
/>
2427
</>
2528
)
2629
}
27-
28-
exportdefaultTemplatesPage

‎site/src/pages/TemplatesPage/TemplatesPageView.stories.tsx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import{ComponentMeta,Story}from"@storybook/react"
2-
import{MockTemplate}from"../../testHelpers/entities"
2+
import{makeMockApiError,MockTemplate}from"../../testHelpers/entities"
33
import{TemplatesPageView,TemplatesPageViewProps}from"./TemplatesPageView"
44

55
exportdefault{
@@ -49,3 +49,8 @@ EmptyCanCreate.args = {
4949

5050
exportconstEmptyCannotCreate=Template.bind({})
5151
EmptyCannotCreate.args={}
52+
53+
exportconstError=Template.bind({})
54+
Error.args={
55+
getTemplatesError:makeMockApiError({message:"Something went wrong fetching templates."}),
56+
}

‎site/src/pages/TemplatesPage/TemplatesPageView.tsx‎

Lines changed: 109 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import TableHead from "@material-ui/core/TableHead"
88
importTableRowfrom"@material-ui/core/TableRow"
99
importKeyboardArrowRightfrom"@material-ui/icons/KeyboardArrowRight"
1010
importuseThemefrom"@material-ui/styles/useTheme"
11+
import{ErrorSummary}from"components/ErrorSummary/ErrorSummary"
1112
import{FC}from"react"
13+
import{useTranslation}from"react-i18next"
1214
import{useNavigate}from"react-router-dom"
1315
import{createDayString}from"util/createDayString"
1416
import{formatTemplateActiveDevelopers}from"util/templates"
@@ -77,12 +79,20 @@ export interface TemplatesPageViewProps {
7779
loading?:boolean
7880
canCreateTemplate?:boolean
7981
templates?:TypesGen.Template[]
82+
getOrganizationsError?:Error|unknown
83+
getTemplatesError?:Error|unknown
8084
}
8185

8286
exportconstTemplatesPageView:FC<React.PropsWithChildren<TemplatesPageViewProps>>=(props)=>{
8387
conststyles=useStyles()
8488
constnavigate=useNavigate()
89+
const{ t}=useTranslation("templatesPage")
8590
consttheme:Theme=useTheme()
91+
constempty=
92+
!props.loading&&
93+
!props.getOrganizationsError&&
94+
!props.getTemplatesError&&
95+
!props.templates?.length
8696

8797
return(
8898
<Margins>
@@ -114,94 +124,110 @@ export const TemplatesPageView: FC<React.PropsWithChildren<TemplatesPageViewProp
114124
)}
115125
</PageHeader>
116126

117-
<TableContainer>
118-
<Table>
119-
<TableHead>
120-
<TableRow>
121-
<TableCellwidth="50%">{Language.nameLabel}</TableCell>
122-
<TableCellwidth="16%">{Language.usedByLabel}</TableCell>
123-
<TableCellwidth="16%">{Language.lastUpdatedLabel}</TableCell>
124-
<TableCellwidth="16%">{Language.createdByLabel}</TableCell>
125-
<TableCellwidth="1%"></TableCell>
126-
</TableRow>
127-
</TableHead>
128-
<TableBody>
129-
{props.loading&&<TableLoader/>}
130-
{!props.loading&&!props.templates?.length&&(
127+
{props.getOrganizationsError ?(
128+
<ErrorSummary
129+
error={props.getOrganizationsError}
130+
defaultMessage={t("errors.getOrganizationsError")}
131+
/>
132+
) :props.getTemplatesError ?(
133+
<ErrorSummary
134+
error={props.getTemplatesError}
135+
defaultMessage={t("errors.getTemplatesError")}
136+
/>
137+
) :(
138+
<TableContainer>
139+
<Table>
140+
<TableHead>
131141
<TableRow>
132-
<TableCellcolSpan={999}>
133-
<EmptyState
134-
message={Language.emptyMessage}
135-
description={
136-
props.canCreateTemplate
137-
?Language.emptyDescription
138-
:Language.emptyViewNoPerms
139-
}
140-
descriptionClassName={styles.emptyDescription}
141-
cta={<CodeExamplecode="coder templates init"/>}
142-
/>
143-
</TableCell>
142+
<TableCellwidth="50%">{Language.nameLabel}</TableCell>
143+
<TableCellwidth="16%">{Language.usedByLabel}</TableCell>
144+
<TableCellwidth="16%">{Language.lastUpdatedLabel}</TableCell>
145+
<TableCellwidth="16%">{Language.createdByLabel}</TableCell>
146+
<TableCellwidth="1%"></TableCell>
144147
</TableRow>
145-
)}
146-
{props.templates?.map((template)=>{
147-
consttemplatePageLink=`/templates/${template.name}`
148-
consthasIcon=template.icon&&template.icon!==""
149-
150-
return(
151-
<TableRow
152-
key={template.id}
153-
hover
154-
data-testid={`template-${template.id}`}
155-
tabIndex={0}
156-
onKeyDown={(event)=>{
157-
if(event.key==="Enter"){
158-
navigate(templatePageLink)
159-
}
160-
}}
161-
className={styles.clickableTableRow}
162-
>
163-
<TableCellLinkto={templatePageLink}>
164-
<AvatarData
165-
title={template.name}
166-
subtitle={template.description}
167-
highlightTitle
168-
avatar={
169-
hasIcon ?(
170-
<divclassName={styles.templateIconWrapper}>
171-
<imgalt=""src={template.icon}/>
172-
</div>
173-
) :undefined
148+
</TableHead>
149+
<TableBody>
150+
{props.loading&&<TableLoader/>}
151+
152+
{empty ?(
153+
<TableRow>
154+
<TableCellcolSpan={999}>
155+
<EmptyState
156+
message={Language.emptyMessage}
157+
description={
158+
props.canCreateTemplate
159+
?Language.emptyDescription
160+
:Language.emptyViewNoPerms
174161
}
162+
descriptionClassName={styles.emptyDescription}
163+
cta={<CodeExamplecode="coder templates init"/>}
175164
/>
176-
</TableCellLink>
177-
178-
<TableCellLinkto={templatePageLink}>
179-
<spanstyle={{color:theme.palette.text.secondary}}>
180-
{Language.developerCount(template.active_user_count)}
181-
</span>
182-
</TableCellLink>
183-
184-
<TableCellLinkdata-chromatic="ignore"to={templatePageLink}>
185-
<spanstyle={{color:theme.palette.text.secondary}}>
186-
{createDayString(template.updated_at)}
187-
</span>
188-
</TableCellLink>
189-
<TableCellLinkto={templatePageLink}>
190-
<spanstyle={{color:theme.palette.text.secondary}}>
191-
{template.created_by_name}
192-
</span>
193-
</TableCellLink>
194-
<TableCellLinkto={templatePageLink}>
195-
<divclassName={styles.arrowCell}>
196-
<KeyboardArrowRightclassName={styles.arrowRight}/>
197-
</div>
198-
</TableCellLink>
165+
</TableCell>
199166
</TableRow>
200-
)
201-
})}
202-
</TableBody>
203-
</Table>
204-
</TableContainer>
167+
) :(
168+
props.templates?.map((template)=>{
169+
consttemplatePageLink=`/templates/${template.name}`
170+
consthasIcon=template.icon&&template.icon!==""
171+
172+
return(
173+
<TableRow
174+
key={template.id}
175+
hover
176+
data-testid={`template-${template.id}`}
177+
tabIndex={0}
178+
onKeyDown={(event)=>{
179+
if(event.key==="Enter"){
180+
navigate(templatePageLink)
181+
}
182+
}}
183+
className={styles.clickableTableRow}
184+
>
185+
<TableCellLinkto={templatePageLink}>
186+
<AvatarData
187+
title={template.name}
188+
subtitle={template.description}
189+
highlightTitle
190+
avatar={
191+
hasIcon&&(
192+
<divclassName={styles.templateIconWrapper}>
193+
<imgalt=""src={template.icon}/>
194+
</div>
195+
)
196+
}
197+
/>
198+
</TableCellLink>
199+
200+
<TableCellLinkto={templatePageLink}>
201+
<spanstyle={{color:theme.palette.text.secondary}}>
202+
{Language.developerCount(template.active_user_count)}
203+
</span>
204+
</TableCellLink>
205+
206+
<TableCellLinkdata-chromatic="ignore"to={templatePageLink}>
207+
<spanstyle={{color:theme.palette.text.secondary}}>
208+
{createDayString(template.updated_at)}
209+
</span>
210+
</TableCellLink>
211+
212+
<TableCellLinkto={templatePageLink}>
213+
<spanstyle={{color:theme.palette.text.secondary}}>
214+
{template.created_by_name}
215+
</span>
216+
</TableCellLink>
217+
218+
<TableCellLinkto={templatePageLink}>
219+
<divclassName={styles.arrowCell}>
220+
<KeyboardArrowRightclassName={styles.arrowRight}/>
221+
</div>
222+
</TableCellLink>
223+
</TableRow>
224+
)
225+
})
226+
)}
227+
</TableBody>
228+
</Table>
229+
</TableContainer>
230+
)}
205231
</Margins>
206232
)
207233
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp