chore: apply design changes to the admin settings menu dropdown (#15947)

resolves coder/internal#177

Design changes for the admin settings menu dropdown

<img width="327" alt="Screenshot 2024-12-20 at 17 44 48"
src="https://github.com/user-attachments/assets/04af04b3-bfa2-4659-b31c-58252bf43c05"
/>
This commit is contained in:
Jaayden Halko
2024-12-20 17:55:19 -05:00
committed by GitHub
parent 809c6114be
commit 5786a13ac9
8 changed files with 42 additions and 61 deletions
+2 -2
View File
@@ -84,7 +84,7 @@ test("change quota settings", async ({ page }) => {
// Go to settings
await page.goto(`/organizations/${org.name}/groups/${group.name}`);
await page.getByRole("button", { name: "Settings" }).click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
expectUrl(page).toHavePathName(
`/organizations/${org.name}/groups/${group.name}/settings`,
);
@@ -99,6 +99,6 @@ test("change quota settings", async ({ page }) => {
);
// ...and that setting should persist if we go back
await page.getByRole("button", { name: "Settings" }).click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
await expect(page.getByLabel("Quota Allowance")).toHaveValue("100");
});
@@ -19,12 +19,14 @@ type FeatureStageBadgeProps = Readonly<
Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
contentType: keyof typeof featureStageBadgeTypes;
size?: "sm" | "md" | "lg";
showTooltip?: boolean;
}
>;
export const FeatureStageBadge: FC<FeatureStageBadgeProps> = ({
contentType,
size = "md",
showTooltip = true, // This is a temporary until the deprecated popover is removed
...delegatedProps
}) => {
return (
@@ -49,24 +51,26 @@ export const FeatureStageBadge: FC<FeatureStageBadgeProps> = ({
)}
</PopoverTrigger>
<HelpTooltipContent
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
transformOrigin={{ vertical: "top", horizontal: "center" }}
>
<p css={styles.tooltipDescription}>
This feature has not yet reached general availability (GA).
</p>
<Link
href={docs("/contributing/feature-stages")}
target="_blank"
rel="noreferrer"
css={styles.tooltipLink}
{showTooltip && (
<HelpTooltipContent
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
transformOrigin={{ vertical: "top", horizontal: "center" }}
>
Learn about feature stages
<span style={visuallyHidden}> (link opens in new tab)</span>
</Link>
</HelpTooltipContent>
<p css={styles.tooltipDescription}>
This feature has not yet reached general availability (GA).
</p>
<Link
href={docs("/contributing/feature-stages")}
target="_blank"
rel="noreferrer"
css={styles.tooltipLink}
>
Learn about feature stages
<span style={visuallyHidden}> (link opens in new tab)</span>
</Link>
</HelpTooltipContent>
)}
</Popover>
);
};
@@ -2,13 +2,14 @@ import { type Interpolation, type Theme, css, useTheme } from "@emotion/react";
import Button from "@mui/material/Button";
import MenuItem from "@mui/material/MenuItem";
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow";
import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge";
import {
Popover,
PopoverContent,
PopoverTrigger,
usePopover,
} from "components/deprecated/Popover/Popover";
import { linkToAuditing, linkToUsers } from "modules/navigation";
import { linkToAuditing } from "modules/navigation";
import type { FC } from "react";
import { NavLink } from "react-router-dom";
@@ -52,7 +53,7 @@ export const DeploymentDropdown: FC<DeploymentDropdownProps> = ({
/>
}
>
Administration
Admin settings
</Button>
</PopoverTrigger>
@@ -81,7 +82,6 @@ export const DeploymentDropdown: FC<DeploymentDropdownProps> = ({
const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({
canViewDeployment,
canViewOrganizations,
canViewAllUsers,
canViewAuditLog,
canViewHealth,
}) => {
@@ -98,7 +98,7 @@ const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({
css={styles.menuItem}
onClick={onPopoverClose}
>
Settings
Deployment
</MenuItem>
)}
{canViewOrganizations && (
@@ -109,16 +109,7 @@ const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({
onClick={onPopoverClose}
>
Organizations
</MenuItem>
)}
{canViewAllUsers && (
<MenuItem
component={NavLink}
to={linkToUsers}
css={styles.menuItem}
onClick={onPopoverClose}
>
Users
<FeatureStageBadge contentType="beta" size="sm" showTooltip={false} />
</MenuItem>
)}
{canViewAuditLog && (
@@ -22,7 +22,7 @@ describe("Navbar", () => {
}),
);
render(<App />);
const deploymentMenu = await screen.findByText("Administration");
const deploymentMenu = await screen.findByText("Admin settings");
await userEvent.click(deploymentMenu);
await waitFor(
() => {
@@ -37,7 +37,7 @@ describe("Navbar", () => {
// by default, user is an Admin with permission to see the audit log,
// but is unlicensed so not entitled to see the audit log
render(<App />);
const deploymentMenu = await screen.findByText("Administration");
const deploymentMenu = await screen.findByText("Admin settings");
await userEvent.click(deploymentMenu);
await waitFor(
() => {
@@ -27,7 +27,7 @@ export const ForAdmin: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(
canvas.getByRole("button", { name: "Administration" }),
canvas.getByRole("button", { name: "Admin settings" }),
);
},
};
@@ -44,7 +44,7 @@ export const ForAuditor: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(
canvas.getByRole("button", { name: "Administration" }),
canvas.getByRole("button", { name: "Admin settings" }),
);
},
};
@@ -61,7 +61,7 @@ export const ForOrgAdmin: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(
canvas.getByRole("button", { name: "Administration" }),
canvas.getByRole("button", { name: "Admin settings" }),
);
},
};
@@ -56,25 +56,6 @@ describe("NavbarView", () => {
expect((templatesLink as HTMLAnchorElement).href).toContain("/templates");
});
it("users nav link has the correct href", async () => {
renderWithAuth(
<NavbarView
proxyContextValue={proxyContextValue}
user={MockUser}
onSignOut={noop}
canViewDeployment
canViewOrganizations
canViewAllUsers
canViewHealth
canViewAuditLog
/>,
);
const deploymentMenu = await screen.findByText("Administration");
await userEvent.click(deploymentMenu);
const userLink = await screen.findByText(navLanguage.users);
expect((userLink as HTMLAnchorElement).href).toContain("/users");
});
it("audit nav link has the correct href", async () => {
renderWithAuth(
<NavbarView
@@ -88,7 +69,7 @@ describe("NavbarView", () => {
canViewAuditLog
/>,
);
const deploymentMenu = await screen.findByText("Administration");
const deploymentMenu = await screen.findByText("Admin settings");
await userEvent.click(deploymentMenu);
const auditLink = await screen.findByText(navLanguage.audit);
expect((auditLink as HTMLAnchorElement).href).toContain("/audit");
@@ -107,7 +88,7 @@ describe("NavbarView", () => {
canViewAuditLog
/>,
);
const deploymentMenu = await screen.findByText("Administration");
const deploymentMenu = await screen.findByText("Admin settings");
await userEvent.click(deploymentMenu);
const deploymentSettingsLink = await screen.findByText(
navLanguage.deployment,
@@ -32,7 +32,7 @@ export const Language = {
templates: "Templates",
users: "Users",
audit: "Audit Logs",
deployment: "Settings",
deployment: "Deployment",
};
interface NavItemsProps {
@@ -8,6 +8,7 @@ import {
BreadcrumbPage,
BreadcrumbSeparator,
} from "components/Breadcrumb/Breadcrumb";
import { FeatureStageBadge } from "components/FeatureStageBadge/FeatureStageBadge";
import { Loader } from "components/Loader/Loader";
import { useAuthenticated } from "contexts/auth/RequireAuth";
import { RequirePermission } from "contexts/auth/RequirePermission";
@@ -81,8 +82,12 @@ const OrganizationSettingsLayout: FC = () => {
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/organizations">
<BreadcrumbLink
href="/organizations"
className="flex items-center gap-2"
>
Organizations
<FeatureStageBadge contentType="beta" size="sm" />
</BreadcrumbLink>
</BreadcrumbItem>
{organization && (