Skip to content

Commit de16e29

Browse files
refactor: Refactor update check banner (#5708)
1 parent d6543c0 commit de16e29

File tree

9 files changed

+258
-233
lines changed

9 files changed

+258
-233
lines changed

site/src/app.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import CssBaseline from "@material-ui/core/CssBaseline"
22
import ThemeProvider from "@material-ui/styles/ThemeProvider"
3-
import { LicenseBanner } from "components/LicenseBanner/LicenseBanner"
4-
import { ServiceBanner } from "components/ServiceBanner/ServiceBanner"
53
import { FC } from "react"
64
import { HelmetProvider } from "react-helmet-async"
75
import { BrowserRouter as Router } from "react-router-dom"
@@ -20,8 +18,6 @@ export const App: FC = () => {
2018
<CssBaseline />
2119
<ErrorBoundary>
2220
<XServiceProvider>
23-
<ServiceBanner />
24-
<LicenseBanner />
2521
<AppRouter />
2622
<GlobalSnackbar />
2723
</XServiceProvider>

site/src/components/DashboardLayout/DashboardLayout.tsx

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,56 @@
11
import { makeStyles } from "@material-ui/core/styles"
2-
import { useActor } from "@xstate/react"
2+
import { useMachine } from "@xstate/react"
33
import { Loader } from "components/Loader/Loader"
4-
import { FC, Suspense, useContext, useEffect } from "react"
5-
import { XServiceContext } from "../../xServices/StateContext"
4+
import { FC, Suspense } from "react"
65
import { Navbar } from "../Navbar/Navbar"
76
import { UpdateCheckBanner } from "components/UpdateCheckBanner/UpdateCheckBanner"
87
import { Margins } from "components/Margins/Margins"
98
import { Outlet } from "react-router-dom"
9+
import { LicenseBanner } from "components/LicenseBanner/LicenseBanner"
10+
import { ServiceBanner } from "components/ServiceBanner/ServiceBanner"
11+
import { updateCheckMachine } from "xServices/updateCheck/updateCheckXService"
12+
import { usePermissions } from "hooks/usePermissions"
13+
import { UpdateCheckResponse } from "api/typesGenerated"
1014

1115
export const DashboardLayout: FC = () => {
1216
const styles = useStyles()
13-
const xServices = useContext(XServiceContext)
14-
const [authState] = useActor(xServices.authXService)
15-
const [updateCheckState, updateCheckSend] = useActor(
16-
xServices.updateCheckXService,
17-
)
18-
19-
useEffect(() => {
20-
if (authState.matches("signedIn")) {
21-
updateCheckSend("CHECK")
22-
} else {
23-
updateCheckSend("CLEAR")
24-
}
25-
}, [authState, updateCheckSend])
17+
const permissions = usePermissions()
18+
const [updateCheckState, updateCheckSend] = useMachine(updateCheckMachine, {
19+
context: {
20+
permissions,
21+
},
22+
})
23+
const { error: updateCheckError, updateCheck } = updateCheckState.context
2624

2725
return (
28-
<div className={styles.site}>
29-
<Navbar />
30-
{updateCheckState.context.show && (
31-
<div className={styles.updateCheckBanner}>
32-
<Margins>
33-
<UpdateCheckBanner
34-
updateCheck={updateCheckState.context.updateCheck}
35-
error={updateCheckState.context.error}
36-
onDismiss={() => updateCheckSend("DISMISS")}
37-
/>
38-
</Margins>
26+
<>
27+
<ServiceBanner />
28+
<LicenseBanner />
29+
30+
<div className={styles.site}>
31+
<Navbar />
32+
33+
{updateCheckState.matches("show") && (
34+
<div className={styles.updateCheckBanner}>
35+
<Margins>
36+
<UpdateCheckBanner
37+
// We can trust when it is show, the update check is filled
38+
// unfortunately, XState does not has typed state - context yet
39+
updateCheck={updateCheck as UpdateCheckResponse}
40+
error={updateCheckError}
41+
onDismiss={() => updateCheckSend("DISMISS")}
42+
/>
43+
</Margins>
44+
</div>
45+
)}
46+
47+
<div className={styles.siteContent}>
48+
<Suspense fallback={<Loader />}>
49+
<Outlet />
50+
</Suspense>
3951
</div>
40-
)}
41-
<div className={styles.siteContent}>
42-
<Suspense fallback={<Loader />}>
43-
<Outlet />
44-
</Suspense>
4552
</div>
46-
</div>
53+
</>
4754
)
4855
}
4956

site/src/components/UpdateCheckBanner/UpdateCheckBanner.test.tsx

Lines changed: 0 additions & 51 deletions
This file was deleted.

site/src/components/UpdateCheckBanner/UpdateCheckBanner.tsx

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,46 @@ import Link from "@material-ui/core/Link"
22
import { AlertBanner } from "components/AlertBanner/AlertBanner"
33
import { Trans, useTranslation } from "react-i18next"
44
import * as TypesGen from "api/typesGenerated"
5-
import { FC, useState } from "react"
5+
import { FC } from "react"
66

77
export interface UpdateCheckBannerProps {
8-
updateCheck?: TypesGen.UpdateCheckResponse
9-
error?: Error | unknown
10-
onDismiss?: () => void
8+
updateCheck: TypesGen.UpdateCheckResponse
9+
error?: unknown
10+
onDismiss: () => void
1111
}
1212

1313
export const UpdateCheckBanner: FC<
1414
React.PropsWithChildren<UpdateCheckBannerProps>
1515
> = ({ updateCheck, error, onDismiss }) => {
1616
const { t } = useTranslation("common")
1717

18-
const isOutdated = updateCheck && !updateCheck.current
19-
20-
const [show, setShow] = useState(error || isOutdated)
21-
22-
const dismiss = () => {
23-
onDismiss && onDismiss()
24-
setShow(false)
25-
}
26-
2718
return (
28-
<>
29-
{show && (
30-
<AlertBanner
31-
severity={error ? "error" : "info"}
32-
error={error}
33-
onDismiss={dismiss}
34-
dismissible
35-
>
36-
<>
37-
{error && <>{t("updateCheck.error")} </>}
38-
{isOutdated && (
39-
<div>
40-
<Trans
41-
t={t}
42-
i18nKey="updateCheck.message"
43-
values={{ version: updateCheck.version }}
44-
>
45-
Coder {"{{version}}"} is now available. View the{" "}
46-
<Link href={updateCheck.url}>release notes</Link> and{" "}
47-
<Link href="https://coder.com/docs/coder-oss/latest/admin/upgrade">
48-
upgrade instructions
49-
</Link>{" "}
50-
for more information.
51-
</Trans>
52-
</div>
53-
)}
54-
</>
55-
</AlertBanner>
56-
)}
57-
</>
19+
<AlertBanner
20+
severity={error ? "error" : "info"}
21+
error={error}
22+
onDismiss={onDismiss}
23+
dismissible
24+
>
25+
<>
26+
{error ? (
27+
t("updateCheck.error")
28+
) : (
29+
<div>
30+
<Trans
31+
t={t}
32+
i18nKey="updateCheck.message"
33+
values={{ version: updateCheck.version }}
34+
>
35+
Coder {"{{version}}"} is now available. View the{" "}
36+
<Link href={updateCheck.url}>release notes</Link> and{" "}
37+
<Link href="https://coder.com/docs/coder-oss/latest/admin/upgrade">
38+
upgrade instructions
39+
</Link>{" "}
40+
for more information.
41+
</Trans>
42+
</div>
43+
)}
44+
</>
45+
</AlertBanner>
5846
)
5947
}

site/src/testHelpers/entities.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,7 @@ export const MockPermissions: Permissions = {
10961096
updateUsers: true,
10971097
viewAuditLog: true,
10981098
viewDeploymentConfig: true,
1099+
viewUpdateCheck: true,
10991100
}
11001101

11011102
export const MockAppearance: TypesGen.AppearanceConfig = {

site/src/xServices/StateContext.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { createContext, FC, ReactNode } from "react"
33
import { ActorRefFrom } from "xstate"
44
import { authMachine } from "./auth/authXService"
55
import { buildInfoMachine } from "./buildInfo/buildInfoXService"
6-
import { updateCheckMachine } from "./updateCheck/updateCheckXService"
76
import { entitlementsMachine } from "./entitlements/entitlementsXService"
87
import { appearanceMachine } from "./appearance/appearanceXService"
98

@@ -12,7 +11,6 @@ interface XServiceContextType {
1211
buildInfoXService: ActorRefFrom<typeof buildInfoMachine>
1312
entitlementsXService: ActorRefFrom<typeof entitlementsMachine>
1413
appearanceXService: ActorRefFrom<typeof appearanceMachine>
15-
updateCheckXService: ActorRefFrom<typeof updateCheckMachine>
1614
}
1715

1816
/**
@@ -33,7 +31,6 @@ export const XServiceProvider: FC<{ children: ReactNode }> = ({ children }) => {
3331
buildInfoXService: useInterpret(buildInfoMachine),
3432
entitlementsXService: useInterpret(entitlementsMachine),
3533
appearanceXService: useInterpret(appearanceMachine),
36-
updateCheckXService: useInterpret(updateCheckMachine),
3734
}}
3835
>
3936
{children}

site/src/xServices/auth/authXService.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const checks = {
1616
viewAuditLog: "viewAuditLog",
1717
viewDeploymentConfig: "viewDeploymentConfig",
1818
createGroup: "createGroup",
19+
viewUpdateCheck: "viewUpdateCheck",
1920
} as const
2021

2122
export const permissionsToCheck = {
@@ -67,6 +68,12 @@ export const permissionsToCheck = {
6768
},
6869
action: "create",
6970
},
71+
[checks.viewUpdateCheck]: {
72+
object: {
73+
resource_type: "update_check",
74+
},
75+
action: "read",
76+
},
7077
} as const
7178

7279
export type Permissions = Record<keyof typeof permissionsToCheck, boolean>

0 commit comments

Comments
 (0)