-
Notifications
You must be signed in to change notification settings - Fork 988
feat(site): add deployment menu to navbar #13401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
7c5a750
aa11ae9
c29e76c
b081a12
9104fce
c3d8207
b28025a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import { css, type Interpolation, type Theme, useTheme } from "@emotion/react"; | ||
import Button from "@mui/material/Button"; | ||
import MenuItem from "@mui/material/MenuItem"; | ||
import { type FC } from "react"; | ||
import { NavLink } from "react-router-dom"; | ||
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; | ||
import { | ||
Popover, | ||
PopoverContent, | ||
PopoverTrigger, | ||
usePopover, | ||
} from "components/Popover/Popover"; | ||
|
||
import { USERS_LINK } from "modules/navigation"; | ||
|
||
interface DeploymentDropdownProps { | ||
canViewAuditLog: boolean; | ||
canViewDeployment: boolean; | ||
canViewAllUsers: boolean; | ||
canViewHealth: boolean; | ||
} | ||
|
||
export const DeploymentDropdown: FC<DeploymentDropdownProps> = ({ | ||
canViewAuditLog, | ||
canViewDeployment, | ||
canViewAllUsers, | ||
canViewHealth, | ||
}) => { | ||
const theme = useTheme(); | ||
|
||
if ( | ||
!canViewAuditLog && | ||
!canViewDeployment && | ||
!canViewAllUsers && | ||
!canViewHealth | ||
) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Popover> | ||
<PopoverTrigger> | ||
<Button> | ||
Deployment | ||
<DropdownArrow | ||
color={theme.experimental.l2.fill.solid} | ||
close={false} | ||
/> | ||
</Button> | ||
</PopoverTrigger> | ||
|
||
<PopoverContent | ||
horizontal="right" | ||
css={{ | ||
".MuiPaper-root": { | ||
minWidth: "auto", | ||
width: 180, | ||
boxShadow: theme.shadows[6], | ||
}, | ||
}} | ||
> | ||
<DeploymentDropdownContent | ||
canViewAuditLog={canViewAuditLog} | ||
canViewDeployment={canViewDeployment} | ||
canViewAllUsers={canViewAllUsers} | ||
canViewHealth={canViewHealth} | ||
/> | ||
</PopoverContent> | ||
</Popover> | ||
); | ||
}; | ||
|
||
const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({ | ||
canViewAuditLog, | ||
canViewDeployment, | ||
canViewAllUsers, | ||
canViewHealth, | ||
}) => { | ||
const popover = usePopover(); | ||
|
||
const onPopoverClose = () => popover.setIsOpen(false); | ||
|
||
return ( | ||
<nav> | ||
{canViewDeployment && ( | ||
<NavLink css={styles.link} to="/deployment/general"> | ||
<MenuItem css={styles.menuItem} onClick={onPopoverClose}> | ||
Settings | ||
</MenuItem> | ||
</NavLink> | ||
)} | ||
{canViewAllUsers && ( | ||
<NavLink css={styles.link} to={USERS_LINK}> | ||
<MenuItem css={styles.menuItem} onClick={onPopoverClose}> | ||
Users | ||
</MenuItem> | ||
</NavLink> | ||
)} | ||
{canViewAuditLog && ( | ||
<NavLink css={styles.link} to="/audit"> | ||
<MenuItem css={styles.menuItem} onClick={onPopoverClose}> | ||
Auditing | ||
</MenuItem> | ||
</NavLink> | ||
)} | ||
{canViewHealth && ( | ||
<NavLink css={styles.link} to="/health"> | ||
<MenuItem css={styles.menuItem} onClick={onPopoverClose}> | ||
Healthcheck | ||
</MenuItem> | ||
</NavLink> | ||
)} | ||
</nav> | ||
); | ||
}; | ||
|
||
const styles = { | ||
link: { | ||
textDecoration: "none", | ||
color: "inherit", | ||
}, | ||
menuItem: (theme) => css` | ||
gap: 20px; | ||
padding: 8px 20px; | ||
font-size: 14px; | ||
|
||
&:hover { | ||
background-color: ${theme.palette.action.hover}; | ||
transition: background-color 0.3s ease; | ||
} | ||
`, | ||
menuItemIcon: (theme) => ({ | ||
color: theme.palette.text.secondary, | ||
width: 20, | ||
height: 20, | ||
}), | ||
} satisfies Record<string, Interpolation<Theme>>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,10 +9,11 @@ import Menu from "@mui/material/Menu"; | |
import MenuItem from "@mui/material/MenuItem"; | ||
import Skeleton from "@mui/material/Skeleton"; | ||
import { visuallyHidden } from "@mui/utils"; | ||
import { type FC, type ReactNode, useRef, useState } from "react"; | ||
import { type FC, useRef, useState } from "react"; | ||
import { NavLink, useLocation, useNavigate } from "react-router-dom"; | ||
import type * as TypesGen from "api/typesGenerated"; | ||
import { Abbr } from "components/Abbr/Abbr"; | ||
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; | ||
import { ExternalImage } from "components/ExternalImage/ExternalImage"; | ||
import { displayError } from "components/GlobalSnackbar/utils"; | ||
import { CoderIcon } from "components/Icons/CoderIcon"; | ||
|
@@ -21,10 +22,7 @@ import { useAuthenticated } from "contexts/auth/RequireAuth"; | |
import type { ProxyContextValue } from "contexts/ProxyContext"; | ||
import { BUTTON_SM_HEIGHT, navHeight } from "theme/constants"; | ||
import { UserDropdown } from "./UserDropdown/UserDropdown"; | ||
|
||
export const USERS_LINK = `/users?filter=${encodeURIComponent( | ||
"status:active", | ||
)}`; | ||
import { DeploymentDropdown } from "./DeploymentDropdown"; | ||
|
||
export interface NavbarViewProps { | ||
logo_url?: string; | ||
|
@@ -44,25 +42,14 @@ export const Language = { | |
templates: "Templates", | ||
users: "Users", | ||
audit: "Audit", | ||
deployment: "Deployment", | ||
deployment: "Settings", | ||
}; | ||
|
||
interface NavItemsProps { | ||
children?: ReactNode; | ||
className?: string; | ||
canViewAuditLog: boolean; | ||
canViewDeployment: boolean; | ||
canViewAllUsers: boolean; | ||
canViewHealth: boolean; | ||
} | ||
|
||
const NavItems: FC<NavItemsProps> = ({ | ||
className, | ||
canViewAuditLog, | ||
canViewDeployment, | ||
canViewAllUsers, | ||
canViewHealth, | ||
}) => { | ||
const NavItems: FC<NavItemsProps> = ({ className }) => { | ||
const location = useLocation(); | ||
const theme = useTheme(); | ||
|
||
|
@@ -83,26 +70,6 @@ const NavItems: FC<NavItemsProps> = ({ | |
<NavLink css={styles.link} to="/templates"> | ||
{Language.templates} | ||
</NavLink> | ||
{canViewAllUsers && ( | ||
<NavLink css={styles.link} to={USERS_LINK}> | ||
{Language.users} | ||
</NavLink> | ||
)} | ||
{canViewAuditLog && ( | ||
<NavLink css={styles.link} to="/audit"> | ||
{Language.audit} | ||
</NavLink> | ||
)} | ||
{canViewDeployment && ( | ||
<NavLink css={styles.link} to="/deployment/general"> | ||
{Language.deployment} | ||
</NavLink> | ||
)} | ||
{canViewHealth && ( | ||
<NavLink css={styles.link} to="/health"> | ||
Health | ||
</NavLink> | ||
)} | ||
</nav> | ||
); | ||
}; | ||
|
@@ -157,12 +124,7 @@ export const NavbarView: FC<NavbarViewProps> = ({ | |
)} | ||
</div> | ||
</div> | ||
<NavItems | ||
canViewAuditLog={canViewAuditLog} | ||
canViewDeployment={canViewDeployment} | ||
canViewAllUsers={canViewAllUsers} | ||
canViewHealth={canViewHealth} | ||
/> | ||
<NavItems /> | ||
</div> | ||
</Drawer> | ||
|
||
|
@@ -174,18 +136,20 @@ export const NavbarView: FC<NavbarViewProps> = ({ | |
)} | ||
</NavLink> | ||
|
||
<NavItems | ||
css={styles.desktopNavItems} | ||
canViewAuditLog={canViewAuditLog} | ||
canViewDeployment={canViewDeployment} | ||
canViewAllUsers={canViewAllUsers} | ||
canViewHealth={canViewHealth} | ||
/> | ||
<NavItems css={styles.desktopNavItems} /> | ||
|
||
<div css={styles.navMenus}> | ||
{proxyContextValue && ( | ||
<ProxyMenu proxyContextValue={proxyContextValue} /> | ||
)} | ||
|
||
<DeploymentDropdown | ||
canViewAuditLog={canViewAuditLog} | ||
canViewDeployment={canViewDeployment} | ||
canViewAllUsers={canViewAllUsers} | ||
canViewHealth={canViewHealth} | ||
/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we can pass the root permissions to the component instead of creating derived values for each option. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eh, I don't mind this. the root permissions names are a lot less clear imo, so having the |
||
|
||
{user && ( | ||
<UserDropdown | ||
user={user} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** | ||
* @fileoverview TODO: centralize navigation code here! URL constants, URL formatting, all of it | ||
*/ | ||
|
||
export const USERS_LINK = `/users?filter=${encodeURIComponent( | ||
"status:active", | ||
)}`; |
Uh oh!
There was an error while loading. Please reload this page.