fix: remove @mui/* dependencies from <TemplateInsightsPage /> (#21993)

This pull-request looks at various components within
`<TemplatesInsightsPage />` and ensures that they aren't using the MUI
variants of components.
This commit is contained in:
Jake Howell
2026-02-09 14:10:55 +11:00
committed by GitHub
parent ceacb1e61e
commit d0f7bbc3bd
3 changed files with 78 additions and 154 deletions
@@ -1,8 +1,13 @@
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import { Button } from "components/Button/Button";
import { CheckIcon, ChevronDownIcon } from "lucide-react";
import { type FC, useRef, useState } from "react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "components/DropdownMenu/DropdownMenu";
import { ChevronDownIcon } from "lucide-react";
import type { FC } from "react";
const insightsIntervals = {
day: {
@@ -21,62 +26,26 @@ interface IntervalMenuProps {
}
export const IntervalMenu: FC<IntervalMenuProps> = ({ value, onChange }) => {
const anchorRef = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState(false);
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button
ref={anchorRef}
id="interval-button"
aria-controls={open ? "interval-menu" : undefined}
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={() => setOpen(true)}
variant="outline"
>
{insightsIntervals[value].label}
<ChevronDownIcon className="size-icon-xs ml-1" />
</Button>
<Menu
id="interval-menu"
anchorEl={anchorRef.current}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "interval-button",
}}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
>
{Object.entries(insightsIntervals).map(([interval, { label }]) => {
return (
<MenuItem
css={{ fontSize: 14, justifyContent: "space-between" }}
key={interval}
onClick={() => {
onChange(interval as InsightsInterval);
handleClose();
}}
>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
{insightsIntervals[value].label}
<ChevronDownIcon className="!size-icon-xs" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuRadioGroup
value={value}
onValueChange={(v) => onChange(v as InsightsInterval)}
>
{Object.entries(insightsIntervals).map(([interval, { label }]) => (
<DropdownMenuRadioItem key={interval} value={interval}>
{label}
<div css={{ width: 16, height: 16 }}>
{value === interval && <CheckIcon className="size-icon-xs" />}
</div>
</MenuItem>
);
})}
</Menu>
</div>
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
);
};
@@ -1,6 +1,3 @@
import { useTheme } from "@emotion/react";
import LinearProgress from "@mui/material/LinearProgress";
import Link from "@mui/material/Link";
import { getErrorDetail, getErrorMessage } from "api/errors";
import {
insightsTemplate,
@@ -29,6 +26,7 @@ import {
HelpTooltipText,
HelpTooltipTitle,
} from "components/HelpTooltip/HelpTooltip";
import { Link } from "components/Link/Link";
import { Loader } from "components/Loader/Loader";
import { Stack } from "components/Stack/Stack";
import {
@@ -37,11 +35,7 @@ import {
TooltipContent,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import {
CircleCheck as CircleCheckIcon,
CircleXIcon,
LinkIcon,
} from "lucide-react";
import { CircleCheck as CircleCheckIcon, CircleXIcon } from "lucide-react";
import { useTemplateLayoutContext } from "pages/TemplatePage/TemplateLayout";
import {
type FC,
@@ -396,15 +390,23 @@ const TemplateUsagePanel: FC<TemplateUsagePanelProps> = ({
className,
...panelProps
}) => {
const theme = useTheme();
// The API returns a row for each app, even if the user didn't use it.
const validUsage = data
?.filter((u) => u.seconds > 0)
.sort((a, b) => b.seconds - a.seconds);
const totalInSeconds =
validUsage?.reduce((total, usage) => total + usage.seconds, 0) ?? 1;
const style = getComputedStyle(document.documentElement);
const successHsl = style
.getPropertyValue("--content-success")
.trim()
.replace(/ /g, ", ");
const warningHsl = style
.getPropertyValue("--content-warning")
.trim()
.replace(/ /g, ", ");
const usageColors = chroma
.scale([theme.roles.success.fill.solid, theme.roles.warning.fill.solid])
.scale([`hsl(${successHsl})`, `hsl(${warningHsl})`])
.mode("lch")
.colors(validUsage?.length ?? 0);
@@ -434,17 +436,15 @@ const TemplateUsagePanel: FC<TemplateUsagePanelProps> = ({
</div>
<Tooltip>
<TooltipTrigger asChild>
<LinearProgress
value={percentage}
variant="determinate"
className="w-full h-2 bg-surface-quaternary"
css={{
"& .MuiLinearProgress-bar": {
<div className="relative w-full h-2 rounded-full bg-surface-quaternary">
<div
className="absolute inset-y-0 left-0 rounded-full"
style={{
width: `${percentage}%`,
backgroundColor: usageColors[i],
borderRadius: 999,
},
}}
/>
}}
/>
</div>
</TooltipTrigger>
<TooltipContent>
{Math.floor(percentage)}%
@@ -497,12 +497,7 @@ const TemplateParametersUsagePanel: FC<TemplateParametersUsagePanelProps> = ({
return (
<div
key={parameter.name}
className="flex items-start gap-6 border-0 border-t border-solid border-surface-quaternary p-6 -mx-6"
css={{
"&:first-of-type": {
borderTop: 0,
},
}}
className="flex items-start gap-6 border-0 border-t border-solid border-surface-quaternary p-6 -mx-6 first:border-t-0"
>
<div className="flex-1">
<div className="font-medium">{label}</div>
@@ -603,14 +598,8 @@ const ParameterUsageLabel: FC<ParameterUsageLabelProps> = ({
if (usage.value.startsWith("http")) {
return (
<Link
href={usage.value}
target="_blank"
rel="noreferrer"
className="flex items-center gap-[1px] text-content-primary"
>
<Link href={usage.value} target="_blank" rel="noreferrer">
<TextValue>{usage.value}</TextValue>
<LinkIcon className="size-icon-xs text-content-link" />
</Link>
);
}
@@ -1,9 +1,14 @@
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import { Button } from "components/Button/Button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "components/DropdownMenu/DropdownMenu";
import dayjs from "dayjs";
import { CheckIcon, ChevronDownIcon } from "lucide-react";
import { type FC, useRef, useState } from "react";
import { ChevronDownIcon } from "lucide-react";
import type { FC } from "react";
import type { DateRangeValue } from "./DateRange";
import { lastWeeks } from "./utils";
@@ -17,70 +22,31 @@ interface WeekPickerProps {
}
export const WeekPicker: FC<WeekPickerProps> = ({ value, onChange }) => {
const anchorRef = useRef<HTMLButtonElement>(null);
const [open, setOpen] = useState(false);
const numberOfWeeks = dayjs(value.endDate).diff(
dayjs(value.startDate),
"week",
);
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button
variant="outline"
ref={anchorRef}
id="interval-button"
aria-controls={open ? "interval-menu" : undefined}
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={() => setOpen(true)}
>
Last {numberOfWeeks} weeks
<ChevronDownIcon />
</Button>
<Menu
id="interval-menu"
anchorEl={anchorRef.current}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "interval-button",
}}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
>
{numberOfWeeksOptions.map((option) => {
const optionRange = lastWeeks(option);
return (
<MenuItem
css={{ fontSize: 14, justifyContent: "space-between" }}
key={option}
onClick={() => {
onChange(optionRange);
handleClose();
}}
>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
Last {numberOfWeeks} weeks
<ChevronDownIcon className="!size-icon-xs" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuRadioGroup
value={String(numberOfWeeks)}
onValueChange={(v) => onChange(lastWeeks(Number(v)))}
>
{numberOfWeeksOptions.map((option) => (
<DropdownMenuRadioItem key={option} value={String(option)}>
Last {option} weeks
<div css={{ width: 16, height: 16 }}>
{numberOfWeeks === option && (
<CheckIcon className="size-icon-xs" />
)}
</div>
</MenuItem>
);
})}
</Menu>
</div>
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
);
};