mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor: replace MUI tooltip in WorkspaceTimings (#21107)
for #19974 Continuing the train of thought from https://github.com/coder/coder/pull/20849#issuecomment-3560666271: it's probably better to do away with a custom tooltip component that's only used in `ResourcesChart`/`ScriptsChart`/`StagesChart` and only slightly differs from our base tooltip
This commit is contained in:
@@ -1,81 +0,0 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
|
||||
import MUITooltip, {
|
||||
type TooltipProps as MUITooltipProps,
|
||||
} from "@mui/material/Tooltip";
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import type { FC, HTMLProps } from "react";
|
||||
import { Link, type LinkProps } from "react-router";
|
||||
|
||||
export type TooltipProps = MUITooltipProps;
|
||||
|
||||
export const Tooltip: FC<TooltipProps> = (props) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<MUITooltip
|
||||
classes={{
|
||||
tooltip: css(styles.tooltip(theme)),
|
||||
...props.classes,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const TooltipTitle: FC<HTMLProps<HTMLSpanElement>> = (props) => {
|
||||
return <span css={styles.title} {...props} />;
|
||||
};
|
||||
|
||||
export const TooltipShortDescription: FC<HTMLProps<HTMLSpanElement>> = (
|
||||
props,
|
||||
) => {
|
||||
return <span css={styles.shortDesc} {...props} />;
|
||||
};
|
||||
|
||||
export const TooltipLink: FC<LinkProps> = (props) => {
|
||||
return (
|
||||
<Link {...props} css={styles.link}>
|
||||
<ExternalLinkIcon className="size-icon-xs" />
|
||||
{props.children}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
tooltip: (theme) => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
maxWidth: "max-content",
|
||||
borderRadius: 8,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
fontWeight: 500,
|
||||
fontSize: 12,
|
||||
color: theme.palette.text.secondary,
|
||||
gap: 4,
|
||||
}),
|
||||
title: (theme) => ({
|
||||
color: theme.palette.text.primary,
|
||||
display: "block",
|
||||
}),
|
||||
link: (theme) => ({
|
||||
color: "inherit",
|
||||
textDecoration: "none",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
|
||||
"&:hover": {
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
|
||||
"& svg": {
|
||||
width: 12,
|
||||
height: 12,
|
||||
},
|
||||
}),
|
||||
shortDesc: {
|
||||
maxWidth: 280,
|
||||
},
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
@@ -1,5 +1,12 @@
|
||||
import { type Theme, useTheme } from "@emotion/react";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "components/Tooltip/Tooltip";
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import { type FC, useState } from "react";
|
||||
import { Link } from "react-router";
|
||||
import { Bar } from "./Chart/Bar";
|
||||
import {
|
||||
Chart,
|
||||
@@ -10,7 +17,6 @@ import {
|
||||
ChartSearch,
|
||||
ChartToolbar,
|
||||
} from "./Chart/Chart";
|
||||
import { Tooltip, TooltipLink, TooltipTitle } from "./Chart/Tooltip";
|
||||
import {
|
||||
calcDuration,
|
||||
calcOffset,
|
||||
@@ -116,23 +122,31 @@ export const ResourcesChart: FC<ResourcesChartProps> = ({
|
||||
key={t.name}
|
||||
yAxisLabelId={encodeURIComponent(t.name)}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
<>
|
||||
<TooltipTitle>{label}</TooltipTitle>
|
||||
{/* Stage boundaries should not have these links */}
|
||||
{!stageBoundary && (
|
||||
<TooltipLink to="">view template</TooltipLink>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Bar
|
||||
value={duration}
|
||||
offset={calcOffset(t.range, generalTiming)}
|
||||
scale={scale}
|
||||
colors={legend.colors}
|
||||
/>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Bar
|
||||
value={duration}
|
||||
offset={calcOffset(t.range, generalTiming)}
|
||||
scale={scale}
|
||||
colors={legend.colors}
|
||||
/>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="bottom"
|
||||
className="flex flex-col gap-1.5 border-surface-quaternary"
|
||||
>
|
||||
<p className="m-0 text-content-primary">{label}</p>
|
||||
{/* Stage boundaries should not have these links */}
|
||||
{!stageBoundary && (
|
||||
<Link
|
||||
to=""
|
||||
className="flex items-center gap-1 no-underline text-xs text-inherit hover:text-content-primary"
|
||||
>
|
||||
<ExternalLinkIcon className="size-icon-xs" />
|
||||
view template
|
||||
</Link>
|
||||
)}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
{formatTime(duration)}
|
||||
</XAxisRow>
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { type Theme, useTheme } from "@emotion/react";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "components/Tooltip/Tooltip";
|
||||
import { type FC, useState } from "react";
|
||||
import { Bar } from "./Chart/Bar";
|
||||
import {
|
||||
@@ -10,7 +15,6 @@ import {
|
||||
ChartSearch,
|
||||
ChartToolbar,
|
||||
} from "./Chart/Chart";
|
||||
import { Tooltip, TooltipTitle } from "./Chart/Tooltip";
|
||||
import {
|
||||
calcDuration,
|
||||
calcOffset,
|
||||
@@ -103,19 +107,21 @@ export const ScriptsChart: FC<ScriptsChartProps> = ({
|
||||
key={t.name}
|
||||
yAxisLabelId={encodeURIComponent(t.name)}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
<TooltipTitle>
|
||||
Script exited with <strong>code {t.exitCode}</strong>
|
||||
</TooltipTitle>
|
||||
}
|
||||
>
|
||||
<Bar
|
||||
value={duration}
|
||||
offset={calcOffset(t.range, generalTiming)}
|
||||
scale={scale}
|
||||
colors={legendsByStatus[t.status].colors}
|
||||
/>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Bar
|
||||
value={duration}
|
||||
offset={calcOffset(t.range, generalTiming)}
|
||||
scale={scale}
|
||||
colors={legendsByStatus[t.status].colors}
|
||||
/>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="bottom"
|
||||
className="border-surface-quaternary text-content-primary"
|
||||
>
|
||||
Script exited with <strong>code {t.exitCode}</strong>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
{formatTime(duration)}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import type { TimingStage } from "api/typesGenerated";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "components/Tooltip/Tooltip";
|
||||
import { CircleAlertIcon, InfoIcon } from "lucide-react";
|
||||
import type { FC } from "react";
|
||||
import { Bar, ClickableBar } from "./Chart/Bar";
|
||||
import { Blocks } from "./Chart/Blocks";
|
||||
import { Chart, ChartContent } from "./Chart/Chart";
|
||||
import {
|
||||
Tooltip,
|
||||
type TooltipProps,
|
||||
TooltipShortDescription,
|
||||
TooltipTitle,
|
||||
} from "./Chart/Tooltip";
|
||||
import {
|
||||
calcDuration,
|
||||
calcOffset,
|
||||
@@ -45,7 +44,10 @@ export type Stage = {
|
||||
/**
|
||||
* The tooltip is used to provide additional information about the stage.
|
||||
*/
|
||||
tooltip: Omit<TooltipProps, "children">;
|
||||
tooltip: {
|
||||
heading: string;
|
||||
description: string;
|
||||
};
|
||||
};
|
||||
|
||||
type StageTiming = {
|
||||
@@ -105,11 +107,22 @@ export const StagesChart: FC<StagesChartProps> = ({
|
||||
>
|
||||
<span css={styles.stageLabel}>
|
||||
{stage.label}
|
||||
<Tooltip {...stage.tooltip}>
|
||||
<InfoIcon
|
||||
className="size-icon-xs"
|
||||
css={styles.info}
|
||||
/>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<InfoIcon
|
||||
className="size-icon-xs"
|
||||
css={styles.info}
|
||||
/>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side="bottom"
|
||||
className="flex flex-col gap-1.5 max-w-xs border-surface-quaternary"
|
||||
>
|
||||
<p className="m-0 text-content-primary">
|
||||
{stage.tooltip.heading}
|
||||
</p>
|
||||
<p className="m-0">{stage.tooltip.description}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</YAxisLabel>
|
||||
@@ -219,14 +232,8 @@ export const provisioningStages: Stage[] = [
|
||||
label: "init",
|
||||
section: "provisioning",
|
||||
tooltip: {
|
||||
title: (
|
||||
<>
|
||||
<TooltipTitle>Terraform initialization</TooltipTitle>
|
||||
<TooltipShortDescription>
|
||||
Download providers & modules.
|
||||
</TooltipShortDescription>
|
||||
</>
|
||||
),
|
||||
heading: "Terraform initialization",
|
||||
description: "Download providers & modules.",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -234,15 +241,9 @@ export const provisioningStages: Stage[] = [
|
||||
label: "plan",
|
||||
section: "provisioning",
|
||||
tooltip: {
|
||||
title: (
|
||||
<>
|
||||
<TooltipTitle>Terraform plan</TooltipTitle>
|
||||
<TooltipShortDescription>
|
||||
Compare state of desired vs actual resources and compute changes to
|
||||
be made.
|
||||
</TooltipShortDescription>
|
||||
</>
|
||||
),
|
||||
heading: "Terraform plan",
|
||||
description:
|
||||
"Compare state of desired vs actual resources and compute changes to be made.",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -250,14 +251,9 @@ export const provisioningStages: Stage[] = [
|
||||
label: "graph",
|
||||
section: "provisioning",
|
||||
tooltip: {
|
||||
title: (
|
||||
<>
|
||||
<TooltipTitle>Terraform graph</TooltipTitle>
|
||||
<TooltipShortDescription>
|
||||
List all resources in plan, used to update coderd database.
|
||||
</TooltipShortDescription>
|
||||
</>
|
||||
),
|
||||
heading: "Terraform graph",
|
||||
description:
|
||||
"List all resources in plan, used to update coderd database.",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -265,15 +261,9 @@ export const provisioningStages: Stage[] = [
|
||||
label: "apply",
|
||||
section: "provisioning",
|
||||
tooltip: {
|
||||
title: (
|
||||
<>
|
||||
<TooltipTitle>Terraform apply</TooltipTitle>
|
||||
<TooltipShortDescription>
|
||||
Execute Terraform plan to create/modify/delete resources into
|
||||
desired states.
|
||||
</TooltipShortDescription>
|
||||
</>
|
||||
),
|
||||
heading: "Terraform apply",
|
||||
description:
|
||||
"Execute Terraform plan to create/modify/delete resources into desired states.",
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -285,14 +275,8 @@ export const agentStages = (section: string): Stage[] => {
|
||||
label: "connect",
|
||||
section,
|
||||
tooltip: {
|
||||
title: (
|
||||
<>
|
||||
<TooltipTitle>Connect</TooltipTitle>
|
||||
<TooltipShortDescription>
|
||||
Establish an RPC connection with the control plane.
|
||||
</TooltipShortDescription>
|
||||
</>
|
||||
),
|
||||
heading: "Connect",
|
||||
description: "Establish an RPC connection with the control plane.",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -300,14 +284,8 @@ export const agentStages = (section: string): Stage[] => {
|
||||
label: "run startup scripts",
|
||||
section,
|
||||
tooltip: {
|
||||
title: (
|
||||
<>
|
||||
<TooltipTitle>Run startup scripts</TooltipTitle>
|
||||
<TooltipShortDescription>
|
||||
Execute each agent startup script.
|
||||
</TooltipShortDescription>
|
||||
</>
|
||||
),
|
||||
heading: "Run startup scripts",
|
||||
description: "Execute each agent startup script.",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user