Skip to content

Commit c064adb

Browse files
committed
feat: Add deployment settings page
This allows deployment admins to view options set on their deployments.
1 parent cb359f6 commit c064adb

16 files changed

+611
-195
lines changed

codersdk/flags.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type DeploymentFlags struct {
3838
OAuth2GithubEnterpriseBaseURL *StringFlag `json:"oauth2_github_enterprise_base_url" typescript:",notnull"`
3939
OIDCAllowSignups *BoolFlag `json:"oidc_allow_signups" typescript:",notnull"`
4040
OIDCClientID *StringFlag `json:"oidc_client_id" typescript:",notnull"`
41-
OIDCClientSecret *StringFlag `json:"oidc_cliet_secret" typescript:",notnull"`
41+
OIDCClientSecret *StringFlag `json:"oidc_client_secret" typescript:",notnull"`
4242
OIDCEmailDomain *StringFlag `json:"oidc_email_domain" typescript:",notnull"`
4343
OIDCIssuerURL *StringFlag `json:"oidc_issuer_url" typescript:",notnull"`
4444
OIDCScopes *StringArrayFlag `json:"oidc_scopes" typescript:",notnull"`
@@ -49,7 +49,7 @@ type DeploymentFlags struct {
4949
TLSCertFiles *StringArrayFlag `json:"tls_cert_files" typescript:",notnull"`
5050
TLSClientCAFile *StringFlag `json:"tls_client_ca_file" typescript:",notnull"`
5151
TLSClientAuth *StringFlag `json:"tls_client_auth" typescript:",notnull"`
52-
TLSKeyFiles *StringArrayFlag `json:"tls_key_tiles" typescript:",notnull"`
52+
TLSKeyFiles *StringArrayFlag `json:"tls_key_files" typescript:",notnull"`
5353
TLSMinVersion *StringFlag `json:"tls_min_version" typescript:",notnull"`
5454
TraceEnable *BoolFlag `json:"trace_enable" typescript:",notnull"`
5555
SecureAuthCookie *BoolFlag `json:"secure_auth_cookie" typescript:",notnull"`

site/src/AppRouter.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ const GeneralSettingsPage = lazy(
7474
const SecuritySettingsPage = lazy(
7575
() => import("./pages/DeploySettingsPage/SecuritySettingsPage"),
7676
)
77-
const MetricsSettingsPage = lazy(
78-
() => import("./pages/DeploySettingsPage/MetricsSettingsPage"),
79-
)
8077
const AuthSettingsPage = lazy(
8178
() => import("./pages/DeploySettingsPage/AuthSettingsPage"),
8279
)
80+
const NetworkSettingsPage = lazy(
81+
() => import("./pages/DeploySettingsPage/NetworkSettingsPage"),
82+
)
8383

8484
export const AppRouter: FC = () => {
8585
const xServices = useContext(XServiceContext)
@@ -280,14 +280,14 @@ export const AppRouter: FC = () => {
280280
}
281281
/>
282282
<Route
283-
path="metrics"
283+
path="network"
284284
element={
285285
<AuthAndFrame>
286286
<RequirePermission
287287
isFeatureVisible={Boolean(permissions?.viewDeploymentFlags)}
288288
>
289289
<DeploySettingsLayout>
290-
<MetricsSettingsPage />
290+
<NetworkSettingsPage />
291291
</DeploySettingsLayout>
292292
</RequirePermission>
293293
</AuthAndFrame>

site/src/api/api.ts

+6
Original file line numberDiff line numberDiff line change
@@ -647,3 +647,9 @@ export const getDeploymentFlags =
647647
const response = await axios.get(`/api/v2/flags/deployment`)
648648
return response.data
649649
}
650+
651+
export const getReplicas =
652+
async (): Promise<TypesGen.Replica[]> => {
653+
const response = await axios.get(`/api/v2/replicas`)
654+
return response.data
655+
}

site/src/api/typesGenerated.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ export interface DeploymentFlags {
293293
readonly oauth2_github_enterprise_base_url: StringFlag
294294
readonly oidc_allow_signups: BoolFlag
295295
readonly oidc_client_id: StringFlag
296-
readonly oidc_cliet_secret: StringFlag
296+
readonly oidc_client_secret: StringFlag
297297
readonly oidc_email_domain: StringFlag
298298
readonly oidc_issuer_url: StringFlag
299299
readonly oidc_scopes: StringArrayFlag
@@ -304,7 +304,7 @@ export interface DeploymentFlags {
304304
readonly tls_cert_files: StringArrayFlag
305305
readonly tls_client_ca_file: StringFlag
306306
readonly tls_client_auth: StringFlag
307-
readonly tls_key_tiles: StringArrayFlag
307+
readonly tls_key_files: StringArrayFlag
308308
readonly tls_min_version: StringFlag
309309
readonly trace_enable: BoolFlag
310310
readonly secure_auth_cookie: BoolFlag

site/src/components/DeploySettingsLayout/Header.tsx

+23-13
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,32 @@ import React from "react"
77
export const Header: React.FC<{
88
title: string | JSX.Element
99
description: string | JSX.Element
10-
docsHref: string
11-
}> = ({ title, description, docsHref }) => {
10+
secondary?: boolean
11+
docsHref?: string
12+
}> = ({ title, description, docsHref, secondary }) => {
1213
const styles = useStyles()
1314

1415
return (
1516
<Stack alignItems="baseline" direction="row" justifyContent="space-between">
1617
<div className={styles.headingGroup}>
17-
<h1 className={styles.title}>{title}</h1>
18+
<h1 className={`${styles.title} ${secondary ? "secondary" : ""}`}>
19+
{title}
20+
</h1>
1821
<span className={styles.description}>{description}</span>
1922
</div>
2023

21-
<Button
22-
size="small"
23-
startIcon={<LaunchOutlined />}
24-
component="a"
25-
href={docsHref}
26-
target="_blank"
27-
variant="outlined"
28-
>
29-
Read the docs
30-
</Button>
24+
{docsHref && (
25+
<Button
26+
size="small"
27+
startIcon={<LaunchOutlined />}
28+
component="a"
29+
href={docsHref}
30+
target="_blank"
31+
variant="outlined"
32+
>
33+
Read the docs
34+
</Button>
35+
)}
3136
</Stack>
3237
)
3338
}
@@ -47,6 +52,11 @@ const useStyles = makeStyles((theme) => ({
4752
margin: 0,
4853
marginBottom: theme.spacing(0.5),
4954
gap: theme.spacing(1),
55+
56+
"&.secondary": {
57+
fontSize: 24,
58+
fontWeight: 500,
59+
},
5060
},
5161

5262
description: {

site/src/components/DeploySettingsLayout/Option.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@ const useStyles = makeStyles((theme) => ({
3232
optionValue: {
3333
fontSize: 14,
3434
fontFamily: MONOSPACE_FONT_FAMILY,
35+
36+
"& ul": {
37+
padding: theme.spacing(2),
38+
},
3539
},
3640
}))

site/src/components/DeploySettingsLayout/Sidebar.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { makeStyles } from "@material-ui/core/styles"
22
import LaunchOutlined from "@material-ui/icons/LaunchOutlined"
3-
import VpnKeyOutlined from "@material-ui/icons/VpnKeyOutlined"
43
import LockRounded from "@material-ui/icons/LockRounded"
5-
import BarChartOutlined from "@material-ui/icons/BarChartOutlined"
4+
import Globe from "@material-ui/icons/Public"
5+
import VpnKeyOutlined from "@material-ui/icons/VpnKeyOutlined"
66
import { Stack } from "components/Stack/Stack"
77
import React, { ElementType, PropsWithChildren, ReactNode } from "react"
88
import { NavLink } from "react-router-dom"
@@ -49,22 +49,22 @@ export const Sidebar: React.FC = () => {
4949
General
5050
</SidebarNavItem>
5151
<SidebarNavItem
52-
href="../security"
53-
icon={<SidebarNavItemIcon icon={LockRounded} />}
52+
href="../auth"
53+
icon={<SidebarNavItemIcon icon={VpnKeyOutlined} />}
5454
>
55-
Security
55+
Authentication
5656
</SidebarNavItem>
5757
<SidebarNavItem
58-
href="../metrics"
59-
icon={<SidebarNavItemIcon icon={BarChartOutlined} />}
58+
href="../network"
59+
icon={<SidebarNavItemIcon icon={Globe} />}
6060
>
61-
Metrics / observability
61+
Network
6262
</SidebarNavItem>
6363
<SidebarNavItem
64-
href="../auth"
65-
icon={<SidebarNavItemIcon icon={VpnKeyOutlined} />}
64+
href="../security"
65+
icon={<SidebarNavItemIcon icon={LockRounded} />}
6666
>
67-
Authentication
67+
Security
6868
</SidebarNavItem>
6969
</nav>
7070
)

site/src/components/Navbar/Navbar.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ export const Navbar: React.FC = () => {
1717
const canViewAuditLog =
1818
featureVisibility[FeatureNames.AuditLog] &&
1919
Boolean(permissions?.viewAuditLog)
20-
const canViewAdmin = Boolean(permissions?.viewDeploymentFlags)
20+
const canViewDeployment = Boolean(permissions?.viewDeploymentFlags)
2121
const onSignOut = () => authSend("SIGN_OUT")
2222

2323
return (
2424
<NavbarView
2525
user={me}
2626
onSignOut={onSignOut}
2727
canViewAuditLog={canViewAuditLog}
28-
canViewAdmin={canViewAdmin}
28+
canViewDeployment={canViewDeployment}
2929
/>
3030
)
3131
}

site/src/components/NavbarView/NavbarView.tsx

+10-10
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,24 @@ export interface NavbarViewProps {
1717
user?: TypesGen.User
1818
onSignOut: () => void
1919
canViewAuditLog: boolean
20-
canViewAdmin: boolean
20+
canViewDeployment: boolean
2121
}
2222

2323
export const Language = {
2424
workspaces: "Workspaces",
2525
templates: "Templates",
2626
users: "Users",
2727
audit: "Audit",
28-
admin: "Admin",
28+
deployment: "Deployment",
2929
}
3030

3131
const NavItems: React.FC<
3232
React.PropsWithChildren<{
3333
className?: string
3434
canViewAuditLog: boolean
35-
canViewAdmin: boolean
35+
canViewDeployment: boolean
3636
}>
37-
> = ({ className, canViewAuditLog, canViewAdmin }) => {
37+
> = ({ className, canViewAuditLog, canViewDeployment }) => {
3838
const styles = useStyles()
3939
const location = useLocation()
4040

@@ -71,10 +71,10 @@ const NavItems: React.FC<
7171
</NavLink>
7272
</ListItem>
7373
)}
74-
{canViewAdmin && (
74+
{canViewDeployment && (
7575
<ListItem button className={styles.item}>
76-
<NavLink className={styles.link} to="/admin">
77-
{Language.admin}
76+
<NavLink className={styles.link} to="/settings/deployment">
77+
{Language.deployment}
7878
</NavLink>
7979
</ListItem>
8080
)}
@@ -85,7 +85,7 @@ export const NavbarView: React.FC<React.PropsWithChildren<NavbarViewProps>> = ({
8585
user,
8686
onSignOut,
8787
canViewAuditLog,
88-
canViewAdmin,
88+
canViewDeployment,
8989
}) => {
9090
const styles = useStyles()
9191
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
@@ -114,7 +114,7 @@ export const NavbarView: React.FC<React.PropsWithChildren<NavbarViewProps>> = ({
114114
</div>
115115
<NavItems
116116
canViewAuditLog={canViewAuditLog}
117-
canViewAdmin={canViewAdmin}
117+
canViewDeployment={canViewDeployment}
118118
/>
119119
</div>
120120
</Drawer>
@@ -126,7 +126,7 @@ export const NavbarView: React.FC<React.PropsWithChildren<NavbarViewProps>> = ({
126126
<NavItems
127127
className={styles.desktopNavItems}
128128
canViewAuditLog={canViewAuditLog}
129-
canViewAdmin={canViewAdmin}
129+
canViewDeployment={canViewDeployment}
130130
/>
131131

132132
<div className={styles.profileButton}>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Story } from "@storybook/react"
2+
import { ReplicasTable, ReplicasTableProps } from "./ReplicasTable"
3+
4+
export default {
5+
title: "components/ReplicasTable",
6+
component: ReplicasTable,
7+
}
8+
9+
const Template: Story<ReplicasTableProps> = (args) => <ReplicasTable {...args} />
10+
11+
export const Single = Template.bind({})
12+
Single.args = {
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { FC } from "react"
2+
import Table from "@material-ui/core/Table"
3+
import TableBody from "@material-ui/core/TableBody"
4+
import TableCell from "@material-ui/core/TableCell"
5+
import TableContainer from "@material-ui/core/TableContainer"
6+
import TableHead from "@material-ui/core/TableHead"
7+
import TableRow from "@material-ui/core/TableRow"
8+
import { Replica } from "api/typesGenerated"
9+
10+
export interface ReplicasTableProps {
11+
replicas: Replica[]
12+
}
13+
14+
export const ReplicasTable: FC<ReplicasTableProps> = ({ replicas }) => {
15+
return (
16+
<TableContainer>
17+
<Table>
18+
<TableHead>
19+
<TableRow>
20+
<TableCell width="33%">Hostname</TableCell>
21+
<TableCell width="33%">Info</TableCell>
22+
<TableCell width="33%">State</TableCell>
23+
</TableRow>
24+
</TableHead>
25+
<TableBody>
26+
{replicas.map((replica) => (
27+
<TableRow key={replica.id}>
28+
<TableCell>
29+
{replica.hostname}
30+
</TableCell>
31+
<TableCell>
32+
Database Latency: {replica.database_latency / 1000}ms Relay
33+
Address: {replica.relay_address}
34+
</TableCell>
35+
</TableRow>
36+
))}
37+
</TableBody>
38+
</Table>
39+
</TableContainer>
40+
)
41+
}

0 commit comments

Comments
 (0)