@coder/backstage-plugin-coder
Version:
Create and manage Coder workspaces from Backstage
166 lines (163 loc) • 5.24 kB
JavaScript
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import { useState, useRef, useEffect } from 'react';
import { useId } from '../../hooks/hookPolyfills.esm.js';
import { useInternalCoderAuth } from '../CoderProvider/CoderAuthProvider.esm.js';
import '../CoderProvider/CoderAppConfigProvider.esm.js';
import '../CoderProvider/CoderProvider.esm.js';
import { useWorkspacesCardContext } from './Root.esm.js';
import { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden.esm.js';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import MoreItemsIcon from '@material-ui/icons/MoreVert';
import Tooltip from '@material-ui/core/Tooltip';
import { makeStyles } from '@material-ui/core';
const REFRESH_THROTTLE_MS = 1e3;
const useStyles = makeStyles((theme) => {
const padding = theme.spacing(0.5);
return {
root: {
padding,
margin: 0,
display: "flex",
justifyContent: "center",
alignItems: "center",
color: theme.palette.text.primary,
width: theme.spacing(4) + padding,
height: theme.spacing(4) + padding,
border: "none",
borderRadius: "9999px",
backgroundColor: "inherit",
lineHeight: 1,
// Buttons don't traditionally have the pointer style, but it's being
// changed to match the cursor style for CreateWorkspaceButtonLink
cursor: "pointer",
"&:hover": {
backgroundColor: theme.palette.action.hover
}
},
menuList: {
"& > li:first-child:focus": {
backgroundColor: theme.palette.action.hover
}
}
};
});
const ExtraActionsButton = ({
menuProps,
buttonRef,
toolTipProps,
tooltipRef,
children,
className,
onClick: outerOnClick,
onClose: outerOnClose,
tooltipText = "See additional workspace actions",
...delegatedButtonProps
}) => {
const {
className: menuListClassName,
ref: menuListRef,
MenuListProps = {},
...delegatedMenuProps
} = menuProps ?? {};
const hookId = useId();
const [loadedAnchor, setLoadedAnchor] = useState();
const refreshWorkspaces = useRefreshWorkspaces();
const { unlinkToken } = useInternalCoderAuth();
const styles = useStyles();
const closeMenu = () => setLoadedAnchor(void 0);
const isOpen = loadedAnchor !== void 0;
const menuId = `${hookId}-menu`;
const buttonId = `${hookId}-button`;
const keyboardInstructionsId = `${hookId}-instructions`;
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(Tooltip, { ref: tooltipRef, title: tooltipText, ...toolTipProps, children: /* @__PURE__ */ jsxs(
"button",
{
ref: buttonRef,
id: buttonId,
"aria-controls": isOpen ? menuId : void 0,
className: `${styles.root} ${className ?? ""}`,
type: "button",
onClick: (event) => {
setLoadedAnchor(event.currentTarget);
outerOnClick?.(event);
},
...delegatedButtonProps,
children: [
children ?? /* @__PURE__ */ jsx(MoreItemsIcon, {}),
/* @__PURE__ */ jsx(VisuallyHidden, { children: tooltipText })
]
}
) }),
/* @__PURE__ */ jsx("p", { hidden: true, id: keyboardInstructionsId, children: "Press the up and down arrow keys to navigate between list items. Press Escape to close the menu." }),
/* @__PURE__ */ jsxs(
Menu,
{
getContentAnchorEl: null,
anchorOrigin: { horizontal: "center", vertical: "bottom" },
id: menuId,
open: isOpen,
anchorEl: loadedAnchor,
MenuListProps: {
variant: "menu",
autoFocusItem: true,
dense: true,
"aria-labelledby": buttonId,
"aria-describedby": keyboardInstructionsId,
className: `${styles.menuList} ${menuListClassName ?? ""}`,
...MenuListProps
},
onClose: (event, reason) => {
closeMenu();
outerOnClose?.(event, reason);
},
...delegatedMenuProps,
children: [
/* @__PURE__ */ jsx(
MenuItem,
{
onClick: () => {
refreshWorkspaces();
closeMenu();
},
children: "Refresh"
}
),
/* @__PURE__ */ jsx(
MenuItem,
{
onClick: () => {
unlinkToken();
closeMenu();
},
children: "Unlink Coder account"
}
)
]
}
)
] });
};
function useRefreshWorkspaces() {
const { workspacesQuery } = useWorkspacesCardContext();
const refreshThrottleIdRef = useRef();
useEffect(() => {
const clearThrottleOnUnmount = () => {
window.clearTimeout(refreshThrottleIdRef.current);
};
return clearThrottleOnUnmount;
}, []);
const refreshWorkspaces = () => {
if (refreshThrottleIdRef.current !== void 0) {
return;
}
workspacesQuery.refetch();
refreshThrottleIdRef.current = window.setTimeout(() => {
refreshThrottleIdRef.current = void 0;
}, REFRESH_THROTTLE_MS);
};
return refreshWorkspaces;
}
export { ExtraActionsButton };
//# sourceMappingURL=ExtraActionsButton.esm.js.map