mirror of https://github.com/coder/coder.git
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { makeStyles } from "@material-ui/core/styles"
|
|
import { useMachine } from "@xstate/react"
|
|
import { Loader } from "components/Loader/Loader"
|
|
import { FC, Suspense } from "react"
|
|
import { Navbar } from "../Navbar/Navbar"
|
|
import { UpdateCheckBanner } from "components/UpdateCheckBanner/UpdateCheckBanner"
|
|
import { Margins } from "components/Margins/Margins"
|
|
import { Outlet } from "react-router-dom"
|
|
import { LicenseBanner } from "components/LicenseBanner/LicenseBanner"
|
|
import { ServiceBanner } from "components/ServiceBanner/ServiceBanner"
|
|
import { updateCheckMachine } from "xServices/updateCheck/updateCheckXService"
|
|
import { usePermissions } from "hooks/usePermissions"
|
|
import { UpdateCheckResponse } from "api/typesGenerated"
|
|
|
|
export const DashboardLayout: FC = () => {
|
|
const styles = useStyles()
|
|
const permissions = usePermissions()
|
|
const [updateCheckState, updateCheckSend] = useMachine(updateCheckMachine, {
|
|
context: {
|
|
permissions,
|
|
},
|
|
})
|
|
const { error: updateCheckError, updateCheck } = updateCheckState.context
|
|
|
|
return (
|
|
<>
|
|
<ServiceBanner />
|
|
<LicenseBanner />
|
|
|
|
<div className={styles.site}>
|
|
<Navbar />
|
|
|
|
{updateCheckState.matches("show") && (
|
|
<div className={styles.updateCheckBanner}>
|
|
<Margins>
|
|
<UpdateCheckBanner
|
|
// We can trust when it is show, the update check is filled
|
|
// unfortunately, XState does not has typed state - context yet
|
|
updateCheck={updateCheck as UpdateCheckResponse}
|
|
error={updateCheckError}
|
|
onDismiss={() => updateCheckSend("DISMISS")}
|
|
/>
|
|
</Margins>
|
|
</div>
|
|
)}
|
|
|
|
<div className={styles.siteContent}>
|
|
<Suspense fallback={<Loader />}>
|
|
<Outlet />
|
|
</Suspense>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
site: {
|
|
display: "flex",
|
|
minHeight: "100vh",
|
|
flexDirection: "column",
|
|
},
|
|
updateCheckBanner: {
|
|
// Add spacing at the top and remove some from the bottom. Removal
|
|
// is necessary to avoid a visual jerk when the banner is dismissed.
|
|
// It also give a more pleasant distance to the site content when
|
|
// the banner is visible.
|
|
marginTop: theme.spacing(2),
|
|
marginBottom: -theme.spacing(2),
|
|
},
|
|
siteContent: {
|
|
flex: 1,
|
|
paddingBottom: theme.spacing(10),
|
|
},
|
|
}))
|