File size: 2,757 Bytes
9b906ea | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | import type { MouseEvent, RefObject } from "react";
import { useTranslation } from "react-i18next";
import { useClickOutsideElement } from "#/hooks/use-click-outside-element";
import { ContextMenu } from "#/ui/context-menu";
import { I18nKey } from "#/i18n/declaration";
import StopCircleIcon from "#/icons/stop-circle.svg?react";
import PlayCircleIcon from "#/icons/play-circle.svg?react";
import { ServerStatusContextMenuIconText } from "./server-status-context-menu-icon-text";
import { ServerStatus } from "./server-status";
import { Divider } from "#/ui/divider";
import { cn } from "#/utils/utils";
import { ExecutionStatus } from "#/types/agent-server/core/base/common";
import { isExecutionActive, isExecutionPaused } from "#/utils/status";
interface ServerStatusContextMenuProps {
onClose: () => void;
onStopServer?: (event: MouseEvent<HTMLButtonElement>) => void;
onStartServer?: (event: MouseEvent<HTMLButtonElement>) => void;
executionStatus: ExecutionStatus | null;
position?: "top" | "bottom";
className?: string;
isPausing?: boolean;
ignoreOutsideClickRef?: RefObject<HTMLElement | null>;
}
export function ServerStatusContextMenu({
onClose,
onStopServer,
onStartServer,
executionStatus,
position = "top",
className = "",
isPausing = false,
ignoreOutsideClickRef,
}: ServerStatusContextMenuProps) {
const { t } = useTranslation("openhands");
const ref = useClickOutsideElement<HTMLUListElement>(
onClose,
ignoreOutsideClickRef,
);
const isActive = isExecutionActive(executionStatus);
const isPaused = isExecutionPaused(executionStatus);
const shouldActionShown = isActive || isPaused;
return (
<ContextMenu
ref={ref}
testId="server-status-context-menu"
position={position}
alignment="left"
size="default"
className={cn("left-2 w-fit min-w-42", className)}
>
<ServerStatus
executionStatus={executionStatus}
isPausing={isPausing}
className="pl-0 pr-2 py-1"
/>
{shouldActionShown && (
<>
<Divider inset="menu" />
{isActive && onStopServer && (
<ServerStatusContextMenuIconText
icon={<StopCircleIcon width={18} height={18} />}
text={t(I18nKey.COMMON$STOP_RUNTIME)}
onClick={onStopServer}
testId="stop-server-button"
/>
)}
{isPaused && onStartServer && (
<ServerStatusContextMenuIconText
icon={<PlayCircleIcon width={18} height={18} />}
text={t(I18nKey.COMMON$START_RUNTIME)}
onClick={onStartServer}
testId="start-server-button"
/>
)}
</>
)}
</ContextMenu>
);
}
|