mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site): improve keyboard navigation in help popovers (#23374)
This commit is contained in:
@@ -7,12 +7,12 @@ import {
|
||||
ChartTooltipContent,
|
||||
} from "#/components/Chart/Chart";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { formatDate } from "#/utils/time";
|
||||
|
||||
const chartConfig = {
|
||||
@@ -120,18 +120,18 @@ export const ActiveUsersTitle: FC<ActiveUsersTitleProps> = ({ interval }) => {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
{interval === "day" ? "Daily" : "Weekly"} Active Users
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger size="small" />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>How do we calculate active users?</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger size="small" />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>How do we calculate active users?</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
When a connection is initiated to a user's workspace they are
|
||||
considered an active user. e.g. apps, web terminal, SSH. This is for
|
||||
measuring user activity and has no connection to license
|
||||
consumption.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import {
|
||||
HelpPopover,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "./HelpPopover";
|
||||
|
||||
const meta: Meta<typeof HelpPopover> = {
|
||||
title: "components/HelpPopover",
|
||||
component: HelpPopover,
|
||||
args: {
|
||||
children: (
|
||||
<>
|
||||
<HelpPopoverTitle>What is a template?</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
A template is a common configuration for your team's workspaces.
|
||||
</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href="https://github.com/coder/coder/">
|
||||
Creating a template
|
||||
</HelpPopoverLink>
|
||||
<HelpPopoverLink href="https://github.com/coder/coder/">
|
||||
Updating a template
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</>
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof HelpPopover>;
|
||||
|
||||
export const Example: Story = {};
|
||||
+23
-25
@@ -1,32 +1,29 @@
|
||||
import { CircleHelpIcon, ExternalLinkIcon } from "lucide-react";
|
||||
import type { FC, HTMLAttributes, PropsWithChildren, ReactNode } from "react";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
type TooltipContentProps,
|
||||
type TooltipProps,
|
||||
TooltipTrigger,
|
||||
} from "#/components/Tooltip/Tooltip";
|
||||
Popover,
|
||||
PopoverContent,
|
||||
type PopoverContentProps,
|
||||
PopoverTrigger,
|
||||
} from "#/components/Popover/Popover";
|
||||
import { cn } from "#/utils/cn";
|
||||
|
||||
type Icon = typeof CircleHelpIcon;
|
||||
|
||||
type Size = "small" | "medium";
|
||||
|
||||
export const HelpTooltipTrigger = TooltipTrigger;
|
||||
export const HelpPopoverTrigger = PopoverTrigger;
|
||||
|
||||
export const HelpTooltipIcon = CircleHelpIcon;
|
||||
export const HelpPopoverIcon = CircleHelpIcon;
|
||||
|
||||
export const HelpTooltip: FC<TooltipProps> = (props) => {
|
||||
return <Tooltip {...props} />;
|
||||
};
|
||||
export const HelpPopover = Popover;
|
||||
|
||||
export const HelpTooltipContent: FC<TooltipContentProps> = ({
|
||||
export const HelpPopoverContent: FC<PopoverContentProps> = ({
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<TooltipContent
|
||||
<PopoverContent
|
||||
side="bottom"
|
||||
align="start"
|
||||
collisionPadding={16}
|
||||
@@ -39,22 +36,23 @@ export const HelpTooltipContent: FC<TooltipContentProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
type HelpTooltipIconTriggerProps = React.ComponentPropsWithRef<"button"> & {
|
||||
type HelpPopoverIconTriggerProps = React.ComponentPropsWithRef<"button"> & {
|
||||
size?: Size;
|
||||
hoverEffect?: boolean;
|
||||
};
|
||||
|
||||
export const HelpTooltipIconTrigger: React.FC<HelpTooltipIconTriggerProps> = ({
|
||||
export const HelpPopoverIconTrigger: React.FC<HelpPopoverIconTriggerProps> = ({
|
||||
size = "medium",
|
||||
children = <HelpTooltipIcon />,
|
||||
children = <HelpPopoverIcon />,
|
||||
hoverEffect = true,
|
||||
className,
|
||||
...buttonProps
|
||||
}) => {
|
||||
return (
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<button
|
||||
{...buttonProps}
|
||||
type="button"
|
||||
aria-label="More info"
|
||||
className={cn(
|
||||
"flex items-center justify-center px-0 py-1",
|
||||
@@ -66,11 +64,11 @@ export const HelpTooltipIconTrigger: React.FC<HelpTooltipIconTriggerProps> = ({
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
</HelpTooltipTrigger>
|
||||
</HelpPopoverTrigger>
|
||||
);
|
||||
};
|
||||
|
||||
export const HelpTooltipTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({
|
||||
export const HelpPopoverTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({
|
||||
children,
|
||||
className,
|
||||
...attrs
|
||||
@@ -88,7 +86,7 @@ export const HelpTooltipTitle: FC<HTMLAttributes<HTMLHeadingElement>> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const HelpTooltipText: FC<HTMLAttributes<HTMLParagraphElement>> = ({
|
||||
export const HelpPopoverText: FC<HTMLAttributes<HTMLParagraphElement>> = ({
|
||||
children,
|
||||
className,
|
||||
...attrs
|
||||
@@ -106,12 +104,12 @@ export const HelpTooltipText: FC<HTMLAttributes<HTMLParagraphElement>> = ({
|
||||
);
|
||||
};
|
||||
|
||||
interface HelpTooltipLink {
|
||||
interface HelpPopoverLink {
|
||||
children?: ReactNode;
|
||||
href: string;
|
||||
}
|
||||
|
||||
export const HelpTooltipLink: FC<HelpTooltipLink> = ({ children, href }) => {
|
||||
export const HelpPopoverLink: FC<HelpPopoverLink> = ({ children, href }) => {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
@@ -125,14 +123,14 @@ export const HelpTooltipLink: FC<HelpTooltipLink> = ({ children, href }) => {
|
||||
);
|
||||
};
|
||||
|
||||
interface HelpTooltipActionProps {
|
||||
interface HelpPopoverActionProps {
|
||||
children?: ReactNode;
|
||||
icon: Icon;
|
||||
onClick: () => void;
|
||||
ariaLabel?: string;
|
||||
}
|
||||
|
||||
export const HelpTooltipAction: FC<HelpTooltipActionProps> = ({
|
||||
export const HelpPopoverAction: FC<HelpPopoverActionProps> = ({
|
||||
children,
|
||||
icon: Icon,
|
||||
onClick,
|
||||
@@ -151,6 +149,6 @@ export const HelpTooltipAction: FC<HelpTooltipActionProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const HelpTooltipLinksGroup: FC<PropsWithChildren> = ({ children }) => {
|
||||
export const HelpPopoverLinksGroup: FC<PropsWithChildren> = ({ children }) => {
|
||||
return <div className="flex flex-col gap-2 mt-4">{children}</div>;
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "./HelpTooltip";
|
||||
|
||||
const meta: Meta<typeof HelpTooltip> = {
|
||||
title: "components/HelpTooltip",
|
||||
component: HelpTooltip,
|
||||
args: {
|
||||
children: (
|
||||
<>
|
||||
<HelpTooltipTitle>What is a template?</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
A template is a common configuration for your team's workspaces.
|
||||
</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/">
|
||||
Creating a template
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/">
|
||||
Updating a template
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</>
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof HelpTooltip>;
|
||||
|
||||
const Example: Story = {};
|
||||
|
||||
export { Example as HelpTooltip };
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { FC, ReactNode } from "react";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIcon,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIcon,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import type { ThemeRole } from "#/theme/roles";
|
||||
import { cn } from "#/utils/cn";
|
||||
|
||||
@@ -34,14 +34,14 @@ export const InfoTooltip: FC<InfoTooltipProps> = ({
|
||||
type = "info",
|
||||
}) => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger size="small" hoverEffect={false}>
|
||||
<HelpTooltipIcon className={cn(tooltipColorClasses[type])} />
|
||||
</HelpTooltipIconTrigger>
|
||||
<HelpTooltipContent>
|
||||
{title && <HelpTooltipTitle>{title}</HelpTooltipTitle>}
|
||||
<HelpTooltipText>{message}</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger size="small" hoverEffect={false}>
|
||||
<HelpPopoverIcon className={cn(tooltipColorClasses[type])} />
|
||||
</HelpPopoverIconTrigger>
|
||||
<HelpPopoverContent>
|
||||
{title && <HelpPopoverTitle>{title}</HelpPopoverTitle>}
|
||||
<HelpPopoverText>{message}</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
import { cn } from "#/utils/cn";
|
||||
|
||||
export type PopoverContentProps = PopoverPrimitive.PopoverContentProps;
|
||||
export type PopoverContentProps = React.ComponentPropsWithRef<
|
||||
typeof PopoverPrimitive.Content
|
||||
> & {
|
||||
disablePortal?: boolean;
|
||||
};
|
||||
|
||||
export type PopoverTriggerProps = PopoverPrimitive.PopoverTriggerProps;
|
||||
|
||||
@@ -13,28 +17,36 @@ export const Popover = PopoverPrimitive.Root;
|
||||
|
||||
export const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
|
||||
export const PopoverContent: React.FC<
|
||||
React.ComponentPropsWithRef<typeof PopoverPrimitive.Content>
|
||||
> = ({ className, align = "center", sideOffset = 4, ...props }) => {
|
||||
return (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
collisionPadding={16}
|
||||
className={cn(
|
||||
`z-50 w-72 rounded-md border border-solid bg-surface-primary
|
||||
text-content-primary shadow-md outline-none
|
||||
max-h-[var(--radix-popper-available-height)] overflow-y-auto
|
||||
data-[state=open]:animate-in data-[state=closed]:animate-out
|
||||
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0
|
||||
data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
||||
data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
|
||||
data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2`,
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
export const PopoverContent: React.FC<PopoverContentProps> = ({
|
||||
className,
|
||||
align = "center",
|
||||
sideOffset = 4,
|
||||
disablePortal,
|
||||
...props
|
||||
}) => {
|
||||
const content = (
|
||||
<PopoverPrimitive.Content
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
collisionPadding={16}
|
||||
className={cn(
|
||||
`z-50 w-72 rounded-md border border-solid bg-surface-primary
|
||||
text-content-primary shadow-md outline-none
|
||||
max-h-[var(--radix-popper-available-height)] overflow-y-auto
|
||||
data-[state=open]:animate-in data-[state=closed]:animate-out
|
||||
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0
|
||||
data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
||||
data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
|
||||
data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2`,
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
return disablePortal ? (
|
||||
content
|
||||
) : (
|
||||
<PopoverPrimitive.Portal>{content}</PopoverPrimitive.Portal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,15 +7,13 @@ import { cn } from "#/utils/cn";
|
||||
|
||||
export const TooltipProvider = TooltipPrimitive.Provider;
|
||||
|
||||
export type TooltipProps = TooltipPrimitive.TooltipProps;
|
||||
|
||||
export const Tooltip = TooltipPrimitive.Root;
|
||||
|
||||
export const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||
|
||||
export const TooltipArrow = TooltipPrimitive.Arrow;
|
||||
|
||||
export type TooltipContentProps = React.ComponentPropsWithRef<
|
||||
type TooltipContentProps = React.ComponentPropsWithRef<
|
||||
typeof TooltipPrimitive.Content
|
||||
> & {
|
||||
disablePortal?: boolean;
|
||||
|
||||
@@ -24,7 +24,7 @@ import type {
|
||||
WorkspaceStatus,
|
||||
} from "#/api/typesGenerated";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import { HelpTooltipTitle } from "#/components/HelpTooltip/HelpTooltip";
|
||||
import { HelpPopoverTitle } from "#/components/HelpPopover/HelpPopover";
|
||||
import { JetBrainsIcon } from "#/components/Icons/JetBrainsIcon";
|
||||
import { RocketIcon } from "#/components/Icons/RocketIcon";
|
||||
import { TerminalIcon } from "#/components/Icons/TerminalIcon";
|
||||
@@ -137,9 +137,9 @@ export const DeploymentBannerView: FC<DeploymentBannerViewProps> = ({
|
||||
>
|
||||
{healthErrors.length > 0 ? (
|
||||
<>
|
||||
<HelpTooltipTitle>
|
||||
<HelpPopoverTitle>
|
||||
We have detected problems with your Coder deployment.
|
||||
</HelpTooltipTitle>
|
||||
</HelpPopoverTitle>
|
||||
<div className="flex flex-col gap-1">
|
||||
{healthErrors.map((error) => (
|
||||
<HealthIssue key={error}>{error}</HealthIssue>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { FC } from "react";
|
||||
import type { DERPRegion, WorkspaceAgent } from "#/api/typesGenerated";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
HelpTooltipTrigger,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
HelpPopoverTrigger,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { cn } from "#/utils/cn";
|
||||
import { getLatencyColor } from "#/utils/latency";
|
||||
|
||||
@@ -41,8 +41,8 @@ export const AgentLatency: FC<AgentLatencyProps> = ({ agent }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span
|
||||
role="presentation"
|
||||
aria-label="latency"
|
||||
@@ -50,13 +50,13 @@ export const AgentLatency: FC<AgentLatencyProps> = ({ agent }) => {
|
||||
>
|
||||
{Math.round(latency.latency_ms)}ms
|
||||
</span>
|
||||
</HelpTooltipTrigger>
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>Latency</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
</HelpPopoverTrigger>
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>Latency</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
This is the latency overhead on non peer to peer connections. The
|
||||
first row is the preferred relay.
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
<div className="flex-col gap-1 mt-4">
|
||||
{Object.entries(agent.latency)
|
||||
.sort(([, a], [, b]) => a.latency_ms - b.latency_ms)
|
||||
@@ -73,7 +73,7 @@ export const AgentLatency: FC<AgentLatencyProps> = ({ agent }) => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,14 +2,14 @@ import { RotateCcwIcon } from "lucide-react";
|
||||
import { type FC, useState } from "react";
|
||||
import type { WorkspaceAgent } from "#/api/typesGenerated";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipAction,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
HelpTooltipTrigger,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverAction,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
HelpPopoverTrigger,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import { agentVersionStatus } from "../../utils/workspace";
|
||||
|
||||
@@ -39,17 +39,17 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
const text = `${opener} This can happen after you update Coder with running workspaces. To fix this, you can stop and start the workspace.`;
|
||||
|
||||
return (
|
||||
<HelpTooltip open={isOpen} onOpenChange={setIsOpen}>
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopover open={isOpen} onOpenChange={setIsOpen}>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span role="status" className="cursor-pointer">
|
||||
{status === agentVersionStatus.Outdated ? "Outdated" : "Deprecated"}
|
||||
</span>
|
||||
</HelpTooltipTrigger>
|
||||
<HelpTooltipContent>
|
||||
</HelpPopoverTrigger>
|
||||
<HelpPopoverContent>
|
||||
<Stack spacing={1}>
|
||||
<div>
|
||||
<HelpTooltipTitle>{title}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{text}</HelpTooltipText>
|
||||
<HelpPopoverTitle>{title}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{text}</HelpPopoverText>
|
||||
</div>
|
||||
|
||||
<Stack spacing={0.5}>
|
||||
@@ -66,8 +66,8 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
<span>{serverVersion}</span>
|
||||
</Stack>
|
||||
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipAction
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverAction
|
||||
icon={RotateCcwIcon}
|
||||
onClick={() => {
|
||||
onUpdate();
|
||||
@@ -76,10 +76,10 @@ export const AgentOutdatedTooltip: FC<AgentOutdatedTooltipProps> = ({
|
||||
ariaLabel="Update workspace"
|
||||
>
|
||||
Update workspace
|
||||
</HelpTooltipAction>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpPopoverAction>
|
||||
</HelpPopoverLinksGroup>
|
||||
</Stack>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,12 +8,12 @@ import type {
|
||||
} from "#/api/typesGenerated";
|
||||
import { ChooseOne, Cond } from "#/components/Conditionals/ChooseOne";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
HelpTooltipTrigger,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
HelpPopoverTrigger,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -52,8 +52,8 @@ const AgentWarningTooltip: FC<AgentWarningTooltipProps> = ({
|
||||
variant = "warning",
|
||||
}) => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTrigger asChild role="status" aria-label={ariaLabel}>
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild role="status" aria-label={ariaLabel}>
|
||||
<TriangleAlertIcon
|
||||
className={cn(
|
||||
"relative size-3.5",
|
||||
@@ -62,10 +62,10 @@ const AgentWarningTooltip: FC<AgentWarningTooltipProps> = ({
|
||||
: "text-content-destructive",
|
||||
)}
|
||||
/>
|
||||
</HelpTooltipTrigger>
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>{title}</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
</HelpPopoverTrigger>
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>{title}</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
{detail}
|
||||
{troubleshootingURL && (
|
||||
<>
|
||||
@@ -75,9 +75,9 @@ const AgentWarningTooltip: FC<AgentWarningTooltipProps> = ({
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -37,10 +37,10 @@ import {
|
||||
import { ChevronDownIcon } from "#/components/AnimatedIcons/ChevronDown";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import {
|
||||
HelpTooltipLink,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopoverLink,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
@@ -258,18 +258,18 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
justifyContent="space-between"
|
||||
alignItems="start"
|
||||
>
|
||||
<HelpTooltipTitle>Listening Ports</HelpTooltipTitle>
|
||||
<HelpTooltipLink
|
||||
<HelpPopoverTitle>Listening Ports</HelpPopoverTitle>
|
||||
<HelpPopoverLink
|
||||
href={docs("/admin/networking/port-forwarding#dashboard")}
|
||||
>
|
||||
Learn more
|
||||
</HelpTooltipLink>
|
||||
</HelpPopoverLink>
|
||||
</Stack>
|
||||
<Stack direction="column" gap={1}>
|
||||
<HelpTooltipText css={{ color: theme.palette.text.secondary }}>
|
||||
<HelpPopoverText css={{ color: theme.palette.text.secondary }}>
|
||||
The listening ports are exclusively accessible to you. Selecting
|
||||
HTTP/S will change the protocol for all listening ports.
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
<Stack direction="row" gap={2} className="pb-2">
|
||||
<FormControl size="small" css={styles.protocolFormControl}>
|
||||
<Select
|
||||
@@ -330,9 +330,9 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
</Stack>
|
||||
</Stack>
|
||||
{filteredListeningPorts.length === 0 && (
|
||||
<HelpTooltipText css={styles.noPortText}>
|
||||
<HelpPopoverText css={styles.noPortText}>
|
||||
No open ports were detected.
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
)}
|
||||
{filteredListeningPorts.map((port) => {
|
||||
const url = portForwardURL(
|
||||
@@ -415,12 +415,12 @@ export const PortForwardPopoverView: FC<PortForwardPopoverViewProps> = ({
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
}}
|
||||
>
|
||||
<HelpTooltipTitle>Shared Ports</HelpTooltipTitle>
|
||||
<HelpTooltipText css={{ color: theme.palette.text.secondary }}>
|
||||
<HelpPopoverTitle>Shared Ports</HelpPopoverTitle>
|
||||
<HelpPopoverText css={{ color: theme.palette.text.secondary }}>
|
||||
{canSharePorts
|
||||
? "Ports can be shared with organization members, other Coder users, or with the public."
|
||||
: "This workspace template does not allow sharing ports. Contact a template administrator to enable port sharing."}
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
{canSharePorts && (
|
||||
<div>
|
||||
{filteredSharedPorts?.map((share) => {
|
||||
|
||||
@@ -5,10 +5,10 @@ import { ChevronDownIcon } from "#/components/AnimatedIcons/ChevronDown";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import { CodeExample } from "#/components/CodeExample/CodeExample";
|
||||
import {
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
@@ -44,9 +44,9 @@ export const AgentSSHButton: FC<AgentSSHButtonProps> = ({
|
||||
align="end"
|
||||
className="py-4 px-6 w-80 text-content-secondary mt-[2px] bg-surface-secondary"
|
||||
>
|
||||
<HelpTooltipText>
|
||||
<HelpPopoverText>
|
||||
Run the following commands to connect with SSH:
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
|
||||
<ol style={{ margin: 0, padding: 0 }}>
|
||||
<Stack spacing={0.5} className="mt-3">
|
||||
@@ -61,25 +61,25 @@ export const AgentSSHButton: FC<AgentSSHButtonProps> = ({
|
||||
</Stack>
|
||||
</ol>
|
||||
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href={docs("/install")}>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href={docs("/install")}>
|
||||
Install Coder CLI
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href={docs("/user-guides/workspace-access/vscode")}>
|
||||
</HelpPopoverLink>
|
||||
<HelpPopoverLink href={docs("/user-guides/workspace-access/vscode")}>
|
||||
Connect via VS Code Remote SSH
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink
|
||||
</HelpPopoverLink>
|
||||
<HelpPopoverLink
|
||||
href={docs("/user-guides/workspace-access/jetbrains")}
|
||||
>
|
||||
Connect via JetBrains IDEs
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href={docs("/user-guides/desktop")}>
|
||||
</HelpPopoverLink>
|
||||
<HelpPopoverLink href={docs("/user-guides/desktop")}>
|
||||
Connect via Coder Desktop
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href={docs("/user-guides/workspace-access#ssh")}>
|
||||
</HelpPopoverLink>
|
||||
<HelpPopoverLink href={docs("/user-guides/workspace-access#ssh")}>
|
||||
SSH configuration
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
@@ -92,9 +92,9 @@ interface SSHStepProps {
|
||||
|
||||
const SSHStep: FC<SSHStepProps> = ({ helpText, codeExample }) => (
|
||||
<li style={{ listStylePosition: "inside" }}>
|
||||
<HelpTooltipText style={{ display: "inline" }}>
|
||||
<HelpPopoverText style={{ display: "inline" }}>
|
||||
<strong className="text-xs">{helpText}</strong>
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
<CodeExample secret={false} code={codeExample} />
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -5,13 +5,13 @@ import type {
|
||||
WorkspaceAgentDevcontainer,
|
||||
} from "#/api/typesGenerated";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipAction,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverAction,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { TooltipTrigger } from "#/components/Tooltip/Tooltip";
|
||||
|
||||
type SubAgentOutdatedTooltipProps = {
|
||||
@@ -33,34 +33,34 @@ export const SubAgentOutdatedTooltip: FC<SubAgentOutdatedTooltipProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpPopover>
|
||||
<TooltipTrigger className="px-0 py-1 bg-transparent text-inherit border-none opacity-50 hover:opacity-100">
|
||||
<span role="status" className="cursor-pointer">
|
||||
Outdated
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<HelpTooltipContent>
|
||||
<HelpPopoverContent>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div>
|
||||
<HelpTooltipTitle>Dev Container Outdated</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopoverTitle>Dev Container Outdated</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
This Dev Container is outdated. This can happen if you modify your
|
||||
devcontainer.json file after the Dev Container has been created.
|
||||
To fix this, you can rebuild the Dev Container.
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
</div>
|
||||
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipAction
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverAction
|
||||
icon={RotateCcwIcon}
|
||||
onClick={onUpdate}
|
||||
ariaLabel="Rebuild Dev Container"
|
||||
>
|
||||
Rebuild Dev Container
|
||||
</HelpTooltipAction>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpPopoverAction>
|
||||
</HelpPopoverLinksGroup>
|
||||
</div>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,15 +9,15 @@ import { getErrorDetail, getErrorMessage } from "#/api/errors";
|
||||
import { templateVersion } from "#/api/queries/templates";
|
||||
import type { Workspace } from "#/api/typesGenerated";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipAction,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
HelpTooltipTrigger,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverAction,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
HelpPopoverTrigger,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { linkToTemplate, useLinks } from "#/modules/navigation";
|
||||
import {
|
||||
useWorkspaceUpdate,
|
||||
@@ -36,22 +36,22 @@ export const WorkspaceOutdatedTooltip: FC<WorkspaceOutdatedTooltipProps> = ({
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<HelpTooltip open={isOpen} onOpenChange={setIsOpen}>
|
||||
<HelpPopover open={isOpen} onOpenChange={setIsOpen}>
|
||||
{children ? (
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span className="flex items-center gap-1.5 cursor-help">
|
||||
<InfoIcon css={styles.icon} size={14} />
|
||||
<span>{children}</span>
|
||||
</span>
|
||||
</HelpTooltipTrigger>
|
||||
</HelpPopoverTrigger>
|
||||
) : (
|
||||
<HelpTooltipIconTrigger size="small" hoverEffect={false}>
|
||||
<HelpPopoverIconTrigger size="small" hoverEffect={false}>
|
||||
<InfoIcon css={styles.icon} />
|
||||
<span className="sr-only">Outdated info</span>
|
||||
</HelpTooltipIconTrigger>
|
||||
</HelpPopoverIconTrigger>
|
||||
)}
|
||||
<WorkspaceOutdatedTooltipContent isOpen={isOpen} workspace={workspace} />
|
||||
</HelpTooltip>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -86,11 +86,11 @@ const WorkspaceOutdatedTooltipContent: FC<TooltipContentProps> = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<HelpTooltipContent disablePortal={false}>
|
||||
<HelpTooltipTitle>Outdated</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopoverContent disablePortal={false}>
|
||||
<HelpPopoverTitle>Outdated</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
This workspace version is outdated and a newer version is available.
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
|
||||
<div css={styles.container}>
|
||||
<div className="leading-[1.6]">
|
||||
@@ -122,15 +122,15 @@ const WorkspaceOutdatedTooltipContent: FC<TooltipContentProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipAction
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverAction
|
||||
icon={RotateCcwIcon}
|
||||
onClick={updateWorkspace.update}
|
||||
>
|
||||
Update
|
||||
</HelpTooltipAction>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpPopoverAction>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
<WorkspaceUpdateDialogs {...updateWorkspace.dialogs} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
export const AIBridgeHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>What is AI Bridge?</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
AI Bridge is a smart gateway for AI that provides centralized
|
||||
management, auditing, and attribution for LLM usage.
|
||||
</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href={docs("/ai-coder/ai-bridge")}>
|
||||
Read the docs
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
export const AIBridgeHelpTooltip: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>What is AI Bridge?</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
AI Bridge is a smart gateway for AI that provides centralized
|
||||
management, auditing, and attribution for LLM usage.
|
||||
</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href={docs("/ai-coder/ai-bridge")}>
|
||||
Read the docs
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
);
|
||||
};
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
PageHeaderSubtitle,
|
||||
PageHeaderTitle,
|
||||
} from "#/components/PageHeader/PageHeader";
|
||||
import { AIBridgeHelpTooltip } from "./AIBridgeHelpTooltip";
|
||||
import { AIBridgeHelpPopover } from "./AIBridgeHelpPopover";
|
||||
|
||||
const AIBridgeLayout: FC<PropsWithChildren> = () => {
|
||||
return (
|
||||
@@ -15,7 +15,7 @@ const AIBridgeLayout: FC<PropsWithChildren> = () => {
|
||||
<PageHeaderTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<span>AI Bridge Logs</span>
|
||||
<AIBridgeHelpTooltip />
|
||||
<AIBridgeHelpPopover />
|
||||
</div>
|
||||
</PageHeaderTitle>
|
||||
<PageHeaderSubtitle>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
const Language = {
|
||||
title: "What is an audit log?",
|
||||
body: "An audit log is a record of events and changes made throughout a system.",
|
||||
docs: "Events we track",
|
||||
};
|
||||
|
||||
export const AuditHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>{Language.title}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{Language.body}</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href={docs("/admin/security/audit-logs")}>
|
||||
{Language.docs}
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
const Language = {
|
||||
title: "What is an audit log?",
|
||||
body: "An audit log is a record of events and changes made throughout a system.",
|
||||
docs: "Events we track",
|
||||
};
|
||||
|
||||
export const AuditHelpTooltip: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>{Language.title}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.body}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href={docs("/admin/security/audit-logs")}>
|
||||
{Language.docs}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
);
|
||||
};
|
||||
@@ -24,7 +24,7 @@ import { TableLoader } from "#/components/TableLoader/TableLoader";
|
||||
import { Timeline } from "#/components/Timeline/Timeline";
|
||||
import { docs } from "#/utils/docs";
|
||||
import { AuditFilter } from "./AuditFilter";
|
||||
import { AuditHelpTooltip } from "./AuditHelpTooltip";
|
||||
import { AuditHelpPopover } from "./AuditHelpPopover";
|
||||
import { AuditLogRow } from "./AuditLogRow/AuditLogRow";
|
||||
|
||||
const Language = {
|
||||
@@ -63,7 +63,7 @@ export const AuditPageView: FC<AuditPageViewProps> = ({
|
||||
<PageHeaderTitle>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.title}</span>
|
||||
<AuditHelpTooltip />
|
||||
<AuditHelpPopover />
|
||||
</Stack>
|
||||
</PageHeaderTitle>
|
||||
<PageHeaderSubtitle>{Language.subtitle}</PageHeaderSubtitle>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
const Language = {
|
||||
title: "Why are some events missing?",
|
||||
body: "The connection log is a best-effort log of workspace access. Some events are reported by workspace agents, and receipt of these events by the server is not guaranteed.",
|
||||
docs: "Connection log documentation",
|
||||
};
|
||||
|
||||
export const ConnectionLogHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>{Language.title}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{Language.body}</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href={docs("/admin/monitoring/connection-logs")}>
|
||||
{Language.docs}
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
const Language = {
|
||||
title: "Why are some events missing?",
|
||||
body: "The connection log is a best-effort log of workspace access. Some events are reported by workspace agents, and receipt of these events by the server is not guaranteed.",
|
||||
docs: "Connection log documentation",
|
||||
};
|
||||
|
||||
export const ConnectionLogHelpTooltip: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>{Language.title}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.body}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href={docs("/admin/monitoring/connection-logs")}>
|
||||
{Language.docs}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
);
|
||||
};
|
||||
@@ -24,7 +24,7 @@ import { TableLoader } from "#/components/TableLoader/TableLoader";
|
||||
import { Timeline } from "#/components/Timeline/Timeline";
|
||||
import { docs } from "#/utils/docs";
|
||||
import { ConnectionLogFilter } from "./ConnectionLogFilter";
|
||||
import { ConnectionLogHelpTooltip } from "./ConnectionLogHelpTooltip";
|
||||
import { ConnectionLogHelpPopover } from "./ConnectionLogHelpPopover";
|
||||
import { ConnectionLogRow } from "./ConnectionLogRow/ConnectionLogRow";
|
||||
|
||||
const Language = {
|
||||
@@ -62,7 +62,7 @@ export const ConnectionLogPageView: FC<ConnectionLogPageViewProps> = ({
|
||||
<PageHeaderTitle>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.title}</span>
|
||||
<ConnectionLogHelpTooltip />
|
||||
<ConnectionLogHelpPopover />
|
||||
</Stack>
|
||||
</PageHeaderTitle>
|
||||
<PageHeaderSubtitle>{Language.subtitle}</PageHeaderSubtitle>
|
||||
|
||||
@@ -28,11 +28,11 @@ import {
|
||||
} from "#/components/Dialog/Dialog";
|
||||
import { EmptyState } from "#/components/EmptyState/EmptyState";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipText,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverText,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Input } from "#/components/Input/Input";
|
||||
import { Label } from "#/components/Label/Label";
|
||||
import { Link } from "#/components/Link/Link";
|
||||
@@ -206,7 +206,7 @@ export const IdpOrgSyncPageView: FC<IdpSyncPageViewProps> = ({
|
||||
<Label htmlFor={`${id}-assign-default-org`}>
|
||||
Assign Default Organization
|
||||
</Label>
|
||||
<AssignDefaultOrgHelpTooltip />
|
||||
<AssignDefaultOrgHelpPopover />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -490,16 +490,16 @@ const OrganizationRow: FC<OrganizationRowProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const AssignDefaultOrgHelpTooltip: FC = () => {
|
||||
const AssignDefaultOrgHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverText>
|
||||
Disabling will remove all users from the default organization if a
|
||||
mapping for the default organization is not defined.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,12 +18,12 @@ import {
|
||||
ComboboxTrigger,
|
||||
} from "#/components/Combobox/Combobox";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Input } from "#/components/Input/Input";
|
||||
import { Label } from "#/components/Label/Label";
|
||||
import { Link } from "#/components/Link/Link";
|
||||
@@ -222,7 +222,7 @@ export const IdpGroupSyncForm: FC<IdpGroupSyncFormProps> = ({
|
||||
<Label htmlFor={`${id}-auto-create-missing-groups`}>
|
||||
Auto create missing groups
|
||||
</Label>
|
||||
<AutoCreateMissingGroupsHelpTooltip />
|
||||
<AutoCreateMissingGroupsHelpPopover />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-between items-start">
|
||||
@@ -445,17 +445,17 @@ const GroupRow: FC<GroupRowProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const AutoCreateMissingGroupsHelpTooltip: FC = () => {
|
||||
const AutoCreateMissingGroupsHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverText>
|
||||
Enabling auto create missing groups will automatically create groups
|
||||
returned by the OIDC provider if they do not exist in Coder.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -464,11 +464,11 @@ const LegacyGroupSyncHeader: FC = () => {
|
||||
<h4 className="text-xl font-medium">
|
||||
<div className="flex items-end gap-2">
|
||||
<span>Legacy group sync settings</span>
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>Legacy group sync settings</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>Legacy group sync settings</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
These settings were configured using environment variables, and
|
||||
only apply to the default organization. It is now recommended to
|
||||
configure IdP sync via the CLI or the UI, which enables sync to be
|
||||
@@ -477,9 +477,9 @@ const LegacyGroupSyncHeader: FC = () => {
|
||||
<Link href={docs("/admin/users/idp-sync")}>
|
||||
Learn more…
|
||||
</Link>
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
</div>
|
||||
</h4>
|
||||
);
|
||||
|
||||
@@ -38,7 +38,7 @@ import { UserAutocomplete } from "#/components/UserAutocomplete/UserAutocomplete
|
||||
import type { PaginationResultInfo } from "#/hooks/usePaginatedQuery";
|
||||
import { AISeatCell } from "#/modules/users/AISeatCell";
|
||||
import { UserGroupsCell } from "#/pages/UsersPage/UsersTable/UserGroupsCell";
|
||||
import { TableColumnHelpTooltip } from "./UserTable/TableColumnHelpTooltip";
|
||||
import { TableColumnHelpPopover } from "./UserTable/TableColumnHelpPopover";
|
||||
import { UserRoleCell } from "./UserTable/UserRoleCell";
|
||||
|
||||
interface OrganizationMembersPageViewProps {
|
||||
@@ -115,20 +115,20 @@ export const OrganizationMembersPageView: FC<
|
||||
<TableHead className="w-2/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>Roles</span>
|
||||
<TableColumnHelpTooltip variant="roles" />
|
||||
<TableColumnHelpPopover variant="roles" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
<TableHead className={showAISeatColumn ? "w-1/6" : "w-2/6"}>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>Groups</span>
|
||||
<TableColumnHelpTooltip variant="groups" />
|
||||
<TableColumnHelpPopover variant="groups" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
{showAISeatColumn && (
|
||||
<TableHead className="w-1/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>AI add-on</span>
|
||||
<TableColumnHelpTooltip variant="ai_addon" />
|
||||
<TableColumnHelpPopover variant="ai_addon" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
)}
|
||||
|
||||
@@ -5,12 +5,12 @@ import type { SlimRole } from "#/api/typesGenerated";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import { CollapsibleSummary } from "#/components/CollapsibleSummary/CollapsibleSummary";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { EditSquare } from "#/components/Icons/EditSquare";
|
||||
import {
|
||||
Popover,
|
||||
@@ -87,15 +87,15 @@ export const EditRolesButton: FC<EditRolesButtonProps> = (props) => {
|
||||
|
||||
if (!canSetRoles) {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger size="small" />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>Externally controlled</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger size="small" />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>Externally controlled</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
Roles for this user are controlled by the OIDC identity provider.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -1,13 +1,13 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
type ColumnHeader = "roles" | "groups" | "ai_addon";
|
||||
@@ -48,25 +48,25 @@ type Props = {
|
||||
variant: ColumnHeader;
|
||||
};
|
||||
|
||||
export const TableColumnHelpTooltip: FC<Props> = ({ variant }) => {
|
||||
export const TableColumnHelpPopover: FC<Props> = ({ variant }) => {
|
||||
const variantLang = Language[variant];
|
||||
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger size="small" />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>{variantLang.title}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{variantLang.text}</HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger size="small" />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>{variantLang.title}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{variantLang.text}</HelpPopoverText>
|
||||
{variantLang.links.length > 0 && (
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpPopoverLinksGroup>
|
||||
{variantLang.links.map((link) => (
|
||||
<HelpTooltipLink key={link.text} href={link.href}>
|
||||
<HelpPopoverLink key={link.text} href={link.href}>
|
||||
{link.text}
|
||||
</HelpTooltipLink>
|
||||
</HelpPopoverLink>
|
||||
))}
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpPopoverLinksGroup>
|
||||
)}
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
@@ -39,12 +39,12 @@ import {
|
||||
type DateRangeValue,
|
||||
} from "#/components/DateRangePicker/DateRangePicker";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Link } from "#/components/Link/Link";
|
||||
import { Loader } from "#/components/Loader/Loader";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
@@ -318,15 +318,15 @@ const UsersLatencyPanel: FC<UsersLatencyPanelProps> = ({
|
||||
<PanelHeader>
|
||||
<PanelTitle className="flex items-center gap-2">
|
||||
Latency by user
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger size="small" />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>How is latency calculated?</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger size="small" />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>How is latency calculated?</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
The median round trip time of user connections to workspaces.
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
</PanelTitle>
|
||||
</PanelHeader>
|
||||
<PanelContent error={error} data={data?.report.users}>
|
||||
@@ -373,16 +373,16 @@ const UsersActivityPanel: FC<UsersActivityPanelProps> = ({
|
||||
<PanelHeader>
|
||||
<PanelTitle className="flex items-center gap-2">
|
||||
Activity by user
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger size="small" />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>How is activity calculated?</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger size="small" />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>How is activity calculated?</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
When a connection is initiated to a user's workspace they
|
||||
are considered an active user. e.g. apps, web terminal, SSH
|
||||
</HelpTooltipText>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverText>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
</PanelTitle>
|
||||
</PanelHeader>
|
||||
<PanelContent error={error} data={data?.report.users}>
|
||||
|
||||
@@ -7,18 +7,18 @@ import * as Yup from "yup";
|
||||
import { ConfirmDialog } from "#/components/Dialogs/ConfirmDialog/ConfirmDialog";
|
||||
import type { DialogProps } from "#/components/Dialogs/Dialog";
|
||||
import { FormFields } from "#/components/Form/Form";
|
||||
import {
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Stack } from "#/components/Stack/Stack";
|
||||
import type { PublishVersionData } from "#/pages/TemplateVersionEditorPage/types";
|
||||
import { getFormHelpers } from "#/utils/formUtils";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "../../components/HelpTooltip/HelpTooltip";
|
||||
import { docs } from "../../utils/docs";
|
||||
|
||||
export const Language = {
|
||||
@@ -120,31 +120,31 @@ export const PublishTemplateVersionDialog: FC<
|
||||
}
|
||||
/>
|
||||
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
|
||||
{/**
|
||||
* 2025-09-03 - Without disablePortal, the tooltip will render under the dialog;
|
||||
* this prop may not need to be set when we switch away from MuiDialog
|
||||
*/}
|
||||
<HelpTooltipContent disablePortal>
|
||||
<HelpTooltipTitle>
|
||||
<HelpPopoverContent disablePortal>
|
||||
<HelpPopoverTitle>
|
||||
{Language.activeVersionHelpTitle}
|
||||
</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
{Language.activeVersionHelpText}
|
||||
</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink
|
||||
</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink
|
||||
href={docs(
|
||||
"/admin/templates/managing-templates#template-update-policies",
|
||||
)}
|
||||
>
|
||||
{Language.activeVersionHelpBody}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
</Stack>
|
||||
</FormFields>
|
||||
</Stack>
|
||||
|
||||
@@ -12,14 +12,14 @@ import { AvatarDataSkeleton } from "#/components/Avatar/AvatarDataSkeleton";
|
||||
import { DeprecatedBadge } from "#/components/Badges/Badges";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Margins } from "#/components/Margins/Margins";
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -68,20 +68,20 @@ const Language = {
|
||||
templateTooltipLink: "Manage templates",
|
||||
};
|
||||
|
||||
const TemplateHelpTooltip: FC = () => {
|
||||
const TemplateHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>{Language.templateTooltipTitle}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.templateTooltipText}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href={docs("/admin/templates")}>
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>{Language.templateTooltipTitle}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{Language.templateTooltipText}</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href={docs("/admin/templates")}>
|
||||
{Language.templateTooltipLink}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -241,7 +241,7 @@ export const TemplatesPageView: FC<TemplatesPageViewProps> = ({
|
||||
<PageHeaderTitle>
|
||||
<Stack spacing={1} direction="row" alignItems="center">
|
||||
Templates
|
||||
<TemplateHelpTooltip />
|
||||
<TemplateHelpPopover />
|
||||
</Stack>
|
||||
</PageHeaderTitle>
|
||||
<PageHeaderSubtitle>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "#/components/Table/Table";
|
||||
import { TableColumnHelpTooltip } from "../../OrganizationSettingsPage/UserTable/TableColumnHelpTooltip";
|
||||
import { TableColumnHelpPopover } from "../../OrganizationSettingsPage/UserTable/TableColumnHelpPopover";
|
||||
import { UsersTableBody } from "./UsersTableBody";
|
||||
|
||||
const Language = {
|
||||
@@ -76,20 +76,20 @@ export const UsersTable: FC<UsersTableProps> = ({
|
||||
<TableHead className="w-2/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.rolesLabel}</span>
|
||||
<TableColumnHelpTooltip variant="roles" />
|
||||
<TableColumnHelpPopover variant="roles" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
<TableHead className="w-1/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.groupsLabel}</span>
|
||||
<TableColumnHelpTooltip variant="groups" />
|
||||
<TableColumnHelpPopover variant="groups" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
{showAISeatColumn && (
|
||||
<TableHead className="w-1/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.aiAddonLabel}</span>
|
||||
<TableColumnHelpTooltip variant="ai_addon" />
|
||||
<TableColumnHelpPopover variant="ai_addon" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
)}
|
||||
|
||||
@@ -13,11 +13,11 @@ import { Button } from "#/components/Button/Button";
|
||||
import { FormFields } from "#/components/Form/Form";
|
||||
import { TopbarButton } from "#/components/FullPageLayout/Topbar";
|
||||
import {
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { Link } from "#/components/Link/Link";
|
||||
import { Loader } from "#/components/Loader/Loader";
|
||||
import {
|
||||
@@ -147,10 +147,10 @@ const BuildParametersPopoverContent: FC<BuildParametersPopoverContentProps> = ({
|
||||
ephemeralParameters.length > 0 ? (
|
||||
<div className="divide-y">
|
||||
<div className="p-5 text-content-secondary">
|
||||
<HelpTooltipTitle>Build Options</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopoverTitle>Build Options</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
These parameters only apply for a single workspace start.
|
||||
</HelpTooltipText>
|
||||
</HelpPopoverText>
|
||||
</div>
|
||||
<div className="border-0 border-solid p-5">
|
||||
<Form
|
||||
@@ -170,19 +170,19 @@ const BuildParametersPopoverContent: FC<BuildParametersPopoverContentProps> = ({
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-5 text-content-secondary">
|
||||
<HelpTooltipTitle>Build Options</HelpTooltipTitle>
|
||||
<HelpTooltipText>
|
||||
<HelpPopoverTitle>Build Options</HelpPopoverTitle>
|
||||
<HelpPopoverText>
|
||||
This template has no ephemeral build options.
|
||||
</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink
|
||||
</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink
|
||||
href={docs(
|
||||
"/admin/templates/extending-templates/parameters#ephemeral-parameters",
|
||||
)}
|
||||
>
|
||||
Read the docs
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
|
||||
@@ -18,10 +18,10 @@ import {
|
||||
TopbarIconButton,
|
||||
} from "#/components/FullPageLayout/Topbar";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipTrigger,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverTrigger,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@@ -259,18 +259,18 @@ const OwnerBreadcrumb: FC<OwnerBreadcrumbProps> = ({
|
||||
ownerAvatarUrl,
|
||||
}) => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span css={styles.breadcrumbSegment}>
|
||||
<Avatar size="sm" fallback={ownerName} src={ownerAvatarUrl} />
|
||||
<span css={styles.breadcrumbText}>{ownerName}</span>
|
||||
</span>
|
||||
</HelpTooltipTrigger>
|
||||
</HelpPopoverTrigger>
|
||||
|
||||
<HelpTooltipContent align="center">
|
||||
<HelpPopoverContent align="center">
|
||||
<AvatarData title={ownerName} subtitle="Owner" src={ownerAvatarUrl} />
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -286,8 +286,8 @@ const OrganizationBreadcrumb: FC<OrganizationBreadcrumbProps> = ({
|
||||
orgIconUrl,
|
||||
}) => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span css={styles.breadcrumbSegment}>
|
||||
<Avatar
|
||||
size="sm"
|
||||
@@ -297,9 +297,9 @@ const OrganizationBreadcrumb: FC<OrganizationBreadcrumbProps> = ({
|
||||
/>
|
||||
<span css={styles.breadcrumbText}>{orgName}</span>
|
||||
</span>
|
||||
</HelpTooltipTrigger>
|
||||
</HelpPopoverTrigger>
|
||||
|
||||
<HelpTooltipContent align="center">
|
||||
<HelpPopoverContent align="center">
|
||||
<AvatarData
|
||||
title={
|
||||
orgPageUrl ? (
|
||||
@@ -327,8 +327,8 @@ const OrganizationBreadcrumb: FC<OrganizationBreadcrumbProps> = ({
|
||||
}
|
||||
imgFallbackText={orgName}
|
||||
/>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -351,8 +351,8 @@ const WorkspaceBreadcrumb: FC<WorkspaceBreadcrumbProps> = ({
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTrigger asChild>
|
||||
<HelpPopover>
|
||||
<HelpPopoverTrigger asChild>
|
||||
<span css={styles.breadcrumbSegment}>
|
||||
<TopbarAvatar
|
||||
src={templateIconUrl}
|
||||
@@ -363,9 +363,9 @@ const WorkspaceBreadcrumb: FC<WorkspaceBreadcrumbProps> = ({
|
||||
{workspaceName}
|
||||
</span>
|
||||
</span>
|
||||
</HelpTooltipTrigger>
|
||||
</HelpPopoverTrigger>
|
||||
|
||||
<HelpTooltipContent align="center">
|
||||
<HelpPopoverContent align="center">
|
||||
<AvatarData
|
||||
title={
|
||||
<Link
|
||||
@@ -395,8 +395,8 @@ const WorkspaceBreadcrumb: FC<WorkspaceBreadcrumbProps> = ({
|
||||
}
|
||||
imgFallbackText={templateDisplayName}
|
||||
/>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
<CopyButton text={workspaceName} label="Copy workspace name" />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpPopover,
|
||||
HelpPopoverContent,
|
||||
HelpPopoverIconTrigger,
|
||||
HelpPopoverLink,
|
||||
HelpPopoverLinksGroup,
|
||||
HelpPopoverText,
|
||||
HelpPopoverTitle,
|
||||
} from "#/components/HelpPopover/HelpPopover";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
const Language = {
|
||||
workspaceTooltipTitle: "What is a workspace?",
|
||||
workspaceTooltipText:
|
||||
"A workspace is your development environment in the cloud. It includes the infrastructure and tools you need to work on your project.",
|
||||
workspaceTooltipLink1: "Create Workspaces",
|
||||
workspaceTooltipLink2: "Connect with SSH",
|
||||
workspaceTooltipLink3: "Editors and IDEs",
|
||||
};
|
||||
|
||||
export const WorkspaceHelpPopover: FC = () => {
|
||||
return (
|
||||
<HelpPopover>
|
||||
<HelpPopoverIconTrigger />
|
||||
<HelpPopoverContent>
|
||||
<HelpPopoverTitle>{Language.workspaceTooltipTitle}</HelpPopoverTitle>
|
||||
<HelpPopoverText>{Language.workspaceTooltipText}</HelpPopoverText>
|
||||
<HelpPopoverLinksGroup>
|
||||
<HelpPopoverLink href={docs("/user-guides")}>
|
||||
{Language.workspaceTooltipLink1}
|
||||
</HelpPopoverLink>
|
||||
<HelpPopoverLink href={docs("/user-guides/workspace-access")}>
|
||||
{Language.workspaceTooltipLink2}
|
||||
</HelpPopoverLink>
|
||||
</HelpPopoverLinksGroup>
|
||||
</HelpPopoverContent>
|
||||
</HelpPopover>
|
||||
);
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
import type { FC } from "react";
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipContent,
|
||||
HelpTooltipIconTrigger,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "#/components/HelpTooltip/HelpTooltip";
|
||||
import { docs } from "#/utils/docs";
|
||||
|
||||
const Language = {
|
||||
workspaceTooltipTitle: "What is a workspace?",
|
||||
workspaceTooltipText:
|
||||
"A workspace is your development environment in the cloud. It includes the infrastructure and tools you need to work on your project.",
|
||||
workspaceTooltipLink1: "Create Workspaces",
|
||||
workspaceTooltipLink2: "Connect with SSH",
|
||||
workspaceTooltipLink3: "Editors and IDEs",
|
||||
};
|
||||
|
||||
export const WorkspaceHelpTooltip: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipIconTrigger />
|
||||
<HelpTooltipContent>
|
||||
<HelpTooltipTitle>{Language.workspaceTooltipTitle}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.workspaceTooltipText}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href={docs("/user-guides")}>
|
||||
{Language.workspaceTooltipLink1}
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href={docs("/user-guides/workspace-access")}>
|
||||
{Language.workspaceTooltipLink2}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltipContent>
|
||||
</HelpTooltip>
|
||||
);
|
||||
};
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
type WorkspaceFilterState,
|
||||
WorkspacesFilter,
|
||||
} from "./filter/WorkspacesFilter";
|
||||
import { WorkspaceHelpTooltip } from "./WorkspaceHelpTooltip";
|
||||
import { WorkspaceHelpPopover } from "./WorkspaceHelpPopover";
|
||||
import { WorkspacesButton } from "./WorkspacesButton";
|
||||
|
||||
const Language = {
|
||||
@@ -110,7 +110,7 @@ export const WorkspacesPageView: FC<WorkspacesPageViewProps> = ({
|
||||
<PageHeaderTitle>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.pageTitle}</span>
|
||||
<WorkspaceHelpTooltip />
|
||||
<WorkspaceHelpPopover />
|
||||
</Stack>
|
||||
</PageHeaderTitle>
|
||||
</PageHeader>
|
||||
|
||||
@@ -9,7 +9,7 @@ import utc from "dayjs/plugin/utc";
|
||||
import type { ReactNode } from "react";
|
||||
import { Link as RouterLink } from "react-router";
|
||||
import type { Template, Workspace } from "#/api/typesGenerated";
|
||||
import { HelpTooltipTitle } from "#/components/HelpTooltip/HelpTooltip";
|
||||
import { HelpPopoverTitle } from "#/components/HelpPopover/HelpPopover";
|
||||
import type { WorkspaceActivityStatus } from "#/modules/workspaces/activity";
|
||||
import { isWorkspaceOn } from "./workspace";
|
||||
|
||||
@@ -119,7 +119,7 @@ export const autostopDisplay = (
|
||||
message: "Required to stop soon",
|
||||
tooltip: (
|
||||
<>
|
||||
<HelpTooltipTitle>Upcoming stop required</HelpTooltipTitle>
|
||||
<HelpPopoverTitle>Upcoming stop required</HelpPopoverTitle>
|
||||
This workspace will be required to stop by{" "}
|
||||
{dayjs(workspace.latest_build.max_deadline).format(
|
||||
"MMMM D [at] h:mm A",
|
||||
@@ -139,11 +139,11 @@ export const autostopDisplay = (
|
||||
};
|
||||
}
|
||||
let title = (
|
||||
<HelpTooltipTitle>Template Autostop requirement</HelpTooltipTitle>
|
||||
<HelpPopoverTitle>Template Autostop requirement</HelpPopoverTitle>
|
||||
);
|
||||
let reason: ReactNode = ` because the ${template.display_name} template has an autostop requirement.`;
|
||||
if (template.autostop_requirement && template.allow_user_autostop) {
|
||||
title = <HelpTooltipTitle>Autostop schedule</HelpTooltipTitle>;
|
||||
title = <HelpPopoverTitle>Autostop schedule</HelpPopoverTitle>;
|
||||
reason = (
|
||||
<span data-chromatic="ignore">
|
||||
{" "}
|
||||
|
||||
Reference in New Issue
Block a user